diff --git a/azure_jumpstart_arcbox/artifacts/ArcServersLogonScript.ps1 b/azure_jumpstart_arcbox/artifacts/ArcServersLogonScript.ps1 index df1e845248..ab80ef2cda 100644 --- a/azure_jumpstart_arcbox/artifacts/ArcServersLogonScript.ps1 +++ b/azure_jumpstart_arcbox/artifacts/ArcServersLogonScript.ps1 @@ -2,6 +2,7 @@ $Env:ArcBoxDir = "C:\ArcBox" $Env:ArcBoxLogsDir = "$Env:ArcBoxDir\Logs" $Env:ArcBoxVMDir = "$Env:ArcBoxDir\Virtual Machines" $Env:ArcBoxIconDir = "$Env:ArcBoxDir\Icons" +$Env:ArcBoxTestsDir = "$Env:ArcBoxDir\Tests" $agentScript = "$Env:ArcBoxDir\agentScript" # Set variables to execute remote powershell scripts on guest VMs @@ -19,7 +20,7 @@ $sas = "*?si=ArcBox-RL&spr=https&sv=2022-11-02&sr=c&sig=vg8VRjM00Ya%2FGa5izAq3b0 # Archive existing log file and create new one $logFilePath = "$Env:ArcBoxLogsDir\ArcServersLogonScript.log" -if ([System.IO.File]::Exists($logFilePath)) { +if (Test-Path $logFilePath) { $archivefile = "$Env:ArcBoxLogsDir\ArcServersLogonScript-" + (Get-Date -Format "yyyyMMddHHmmss") Rename-Item -Path $logFilePath -NewName $archivefile -Force } @@ -40,6 +41,27 @@ foreach ($key in $keys) { } } +# Create Windows Terminal desktop shortcut +$WshShell = New-Object -comObject WScript.Shell +$WinTerminalPath = (Get-ChildItem "C:\Program Files\WindowsApps" -Recurse | Where-Object { $_.name -eq "wt.exe" }).FullName +$Shortcut = $WshShell.CreateShortcut("$Env:USERPROFILE\Desktop\Windows Terminal.lnk") +$Shortcut.TargetPath = $WinTerminalPath +$shortcut.WindowStyle = 3 +$shortcut.Save() + +# Configure Windows Terminal as the default terminal application +$registryPath = "HKCU:\Console\%%Startup" + +if (Test-Path $registryPath) { + Set-ItemProperty -Path $registryPath -Name "DelegationConsole" -Value "{2EACA947-7F5F-4CFA-BA87-8F7FBEEFBE69}" + Set-ItemProperty -Path $registryPath -Name "DelegationTerminal" -Value "{E12CFF52-A866-4C77-9A90-F570A7AA2C6B}" +} else { + New-Item -Path $registryPath -Force | Out-Null + Set-ItemProperty -Path $registryPath -Name "DelegationConsole" -Value "{2EACA947-7F5F-4CFA-BA87-8F7FBEEFBE69}" + Set-ItemProperty -Path $registryPath -Name "DelegationTerminal" -Value "{E12CFF52-A866-4C77-9A90-F570A7AA2C6B}" +} + + ################################################ # Setup Hyper-V server before deploying VMs for each flavor ################################################ @@ -122,20 +144,26 @@ if ($Env:flavor -ne "DevOps") { # Install Azure CLI extensions Write-Header "Az CLI extensions" - az extension add --name ssh --yes --only-show-errors - az extension add --name log-analytics-solution --yes --only-show-errors - az extension add --name connectedmachine --yes --only-show-errors + + az config set extension.use_dynamic_install=yes_without_prompt --only-show-errors + + @("ssh","log-analytics-solution","connectedmachine") | + ForEach-Object -Parallel { + az extension add --name $PSItem --yes --only-show-errors + } # Required for CLI commands Write-Header "Az CLI Login" az login --service-principal --username $spnClientId --password $spnClientSecret --tenant $spnTenantId + Write-Header "Az PowerShell Login" + Connect-AzAccount -ServicePrincipal -Credential $spncredential -Tenant $env:spntenantId -Subscription $env:subscriptionId + # Register Azure providers Write-Header "Registering Providers" - az provider register --namespace Microsoft.HybridCompute --wait --only-show-errors - az provider register --namespace Microsoft.HybridConnectivity --wait --only-show-errors - az provider register --namespace Microsoft.GuestConfiguration --wait --only-show-errors - az provider register --namespace Microsoft.AzureArcData --wait --only-show-errors + @("Microsoft.HybridCompute","Microsoft.HybridConnectivity","Microsoft.GuestConfiguration","Microsoft.AzureArcData") | ForEach-Object -Parallel { + az provider register --namespace $PSItem --wait --only-show-errors + } # Enable defender for cloud for SQL Server # Verify existing plan and update accordingly @@ -171,7 +199,7 @@ if ($Env:flavor -ne "DevOps") { Write-Host "Fetching SQL VM" # Verify if VHD files already downloaded especially when re-running this script - if (!([System.IO.File]::Exists($SQLvmvhdPath) )) { + if (!(Test-Path $SQLvmvhdPath)) { <# Action when all if and elseif conditions are false #> $Env:AZCOPY_BUFFER_GB = 4 # Other ArcBox flavors does not have an azcopy network throughput capping @@ -219,14 +247,6 @@ if ($Env:flavor -ne "DevOps") { Write-Output "Onboarding the nested Windows VMs as Azure Arc-enabled servers" Invoke-Command -VMName $SQLvmName -ScriptBlock { powershell -File $Using:nestedVMArcBoxDir\installArcAgentSQL.ps1 -spnClientId $Using:spnClientId, -spnClientSecret $Using:spnClientSecret, -spnTenantId $Using:spnTenantId, -subscriptionId $Using:subscriptionId, -resourceGroup $Using:resourceGroup, -azureLocation $Using:azureLocation } -Credential $winCreds - # Configure SSH on the nested Windows VMs - Write-Output "Configuring SSH via Azure Arc agent on the nested Windows VMs" - Invoke-Command -VMName $SQLvmName -ScriptBlock { - # Allow SSH via Azure Arc agent - azcmagent config set incomingconnections.ports 22 - } -Credential $winCreds - - # Install Log Analytics extension to support Defender for SQL $mmaExtension = az connectedmachine extension list --machine-name $SQLvmName --resource-group $resourceGroup --query "[?name=='MicrosoftMonitoringAgent']" | ConvertFrom-Json if ($mmaExtension.Count -le 0) { @@ -243,8 +263,8 @@ if ($Env:flavor -ne "DevOps") { $retryCount = 0 do { Start-Sleep(60) - $amaExtension = az connectedmachine extension list --machine-name $SQLvmName --resource-group $resourceGroup --query "[?name=='AzureMonitorWindowsAgent']" | ConvertFrom-Json - if ($amaExtension[0].properties.instanceView.status.code -eq 0) { + $amaExtension = Get-AzConnectedMachine -Name $SQLvmName -ResourceGroupName $resourceGroup | Select-Object -ExpandProperty Resource | Where-Object {$PSItem.Name -eq 'AzureMonitorWindowsAgent'} + if ($amaExtension.StatusCode -eq 0) { Write-Host "Azure Monitoring Agent extension installation complete." break } @@ -259,16 +279,16 @@ if ($Env:flavor -ne "DevOps") { } while ($retryCount -le 5) # Enable Best practices assessment - if ($amaExtension[0].properties.instanceView.status.code -eq 0) { + if ($amaExtension.StatusCode -eq 0) { # Create custom log analytics table for SQL assessment az monitor log-analytics workspace table create --resource-group $resourceGroup --workspace-name $Env:workspaceName -n SqlAssessment_CL --columns RawData=string TimeGenerated=datetime --only-show-errors # Verify if Arc-enabled server and SQL server extensions are installed - $ArcServer = az connectedmachine show --name $SQLvmName --resource-group $resourceGroup - if ($null -ne $ArcServer) { - $sqlExtension = az connectedmachine extension list --machine-name $SQLvmName --resource-group $resourceGroup --query "[?name=='WindowsAgent.SqlServer']" | ConvertFrom-Json - if ($null -ne $sqlExtension) { + $ArcServer = Get-AzConnectedMachine -Name $SQLvmName -ResourceGroupName $resourceGroup + if ($ArcServer) { + $sqlExtension = $ArcServer | Select-Object -ExpandProperty Resource | Where-Object {$PSItem.Name -eq 'WindowsAgent.SqlServer'} + if ($sqlExtension) { # SQL server extension is installed and ready to run SQL BPA Write-Host "SQL server extension is installed and ready to run SQL BPA." } @@ -348,7 +368,7 @@ if ($Env:flavor -ne "DevOps") { $Ubuntu02vmvhdPath = "${Env:ArcBoxVMDir}\${Ubuntu02vmName}.vhdx" # Verify if VHD files already downloaded especially when re-running this script - if (!([System.IO.File]::Exists($win2k19vmvhdPath) -and [System.IO.File]::Exists($Win2k22vmvhdPath) -and [System.IO.File]::Exists($Ubuntu01vmvhdPath) -and [System.IO.File]::Exists($Ubuntu02vmvhdPath))) { + if (!((Test-Path $win2k19vmvhdPath) -and (Test-Path $Win2k22vmvhdPath) -and (Test-Path $Ubuntu01vmvhdPath) -and (Test-Path $Ubuntu02vmvhdPath))) { <# Action when all if and elseif conditions are false #> $Env:AZCOPY_BUFFER_GB = 4 if ($Env:flavor -eq "Full") { @@ -444,8 +464,19 @@ if ($Env:flavor -ne "DevOps") { # Onboarding the nested VMs as Azure Arc-enabled servers Write-Output "Onboarding the nested Windows VMs as Azure Arc-enabled servers" - Invoke-Command -VMName $Win2k19vmName -ScriptBlock { powershell -File $Using:nestedVMArcBoxDir\installArcAgent.ps1 -spnClientId $Using:spnClientId, -spnClientSecret $Using:spnClientSecret, -spnTenantId $Using:spnTenantId, -subscriptionId $Using:subscriptionId, -resourceGroup $Using:resourceGroup, -azureLocation $Using:azureLocation } -Credential $winCreds - Invoke-Command -VMName $Win2k22vmName -ScriptBlock { powershell -File $Using:nestedVMArcBoxDir\installArcAgent.ps1 -spnClientId $Using:spnClientId, -spnClientSecret $Using:spnClientSecret, -spnTenantId $Using:spnTenantId, -subscriptionId $Using:subscriptionId, -resourceGroup $Using:resourceGroup, -azureLocation $Using:azureLocation } -Credential $winCreds + $Win2k19vmName,$Win2k22vmName | ForEach-Object -Parallel { + + $nestedVMArcBoxDir = $Using:nestedVMArcBoxDir + $spnClientId = $Using:spnClientId + $spnClientSecret = $Using:spnClientSecret + $spnTenantId = $Using:spnTenantId + $subscriptionId = $Using:subscriptionId + $resourceGroup = $Using:resourceGroup + $azureLocation = $Using:azureLocation + + Invoke-Command -VMName $PSItem -ScriptBlock { powershell -File $Using:nestedVMArcBoxDir\installArcAgent.ps1 -spnClientId $Using:spnClientId, -spnClientSecret $Using:spnClientSecret, -spnTenantId $Using:spnTenantId, -subscriptionId $Using:subscriptionId, -resourceGroup $Using:resourceGroup, -azureLocation $Using:azureLocation } -Credential $using:winCreds + + } Write-Output "Onboarding the nested Linux VMs as an Azure Arc-enabled servers" $ubuntuSession = New-SSHSession -ComputerName $Ubuntu01VmIp -Credential $linCreds -Force -WarningAction SilentlyContinue @@ -456,12 +487,36 @@ if ($Env:flavor -ne "DevOps") { $Command = "sudo sh /home/$nestedLinuxUsername/installArcAgentModifiedUbuntu.sh" $(Invoke-SSHCommand -SSHSession $ubuntuSession -Command $Command -Timeout 600 -WarningAction SilentlyContinue).Output - # Configure SSH on the nested Windows VMs - Write-Output "Configuring SSH via Azure Arc agent on the nested Windows VMs" - Invoke-Command -VMName $Win2k19vmName, $Win2k22vmName -ScriptBlock { - # Allow SSH via Azure Arc agent - azcmagent config set incomingconnections.ports 22 - } -Credential $winCreds + } + + Write-Header "Enabling SSH access to Arc-enabled servers" + $VMs = @("ArcBox-SQL", "ArcBox-Ubuntu-01", "ArcBox-Ubuntu-02", "ArcBox-Win2K19", "ArcBox-Win2K22") + $VMs | ForEach-Object -Parallel { + + $spnpassword = ConvertTo-SecureString $env:spnClientSecret -AsPlainText -Force + $spncredential = New-Object System.Management.Automation.PSCredential ($env:spnClientId, $spnpassword) + + $null = Connect-AzAccount -ServicePrincipal -Credential $spncredential -Tenant $env:spntenantId -Subscription $env:subscriptionId -Scope Process -WarningAction SilentlyContinue + + $vm = $PSItem + $connectedMachine = Get-AzConnectedMachine -Name $vm -ResourceGroupName $env:resourceGroup -SubscriptionId $env:subscriptionId + + $connectedMachineEndpoint = (Invoke-AzRestMethod -Method get -Path "$($connectedMachine.Id)/providers/Microsoft.HybridConnectivity/endpoints/default?api-version=2023-03-15").Content | ConvertFrom-Json + + if (-not ($connectedMachineEndpoint.properties | Where-Object { $_.type -eq "default" -and $_.provisioningState -eq "Succeeded" })) { + Write-Output "Creating default endpoint for $($connectedMachine.Name)" + $null = Invoke-AzRestMethod -Method put -Path "$($connectedMachine.Id)/providers/Microsoft.HybridConnectivity/endpoints/default?api-version=2023-03-15" -Payload '{"properties": {"type": "default"}}' + } + $connectedMachineSshEndpoint = (Invoke-AzRestMethod -Method get -Path "$($connectedMachine.Id)/providers/Microsoft.HybridConnectivity/endpoints/default/serviceconfigurations/SSH?api-version=2023-03-15").Content | ConvertFrom-Json + + if (-not ($connectedMachineSshEndpoint.properties | Where-Object { $_.serviceName -eq "SSH" -and $_.provisioningState -eq "Succeeded" })) { + Write-Output "Enabling SSH on $($connectedMachine.Name)" + $null = Invoke-AzRestMethod -Method put -Path "$($connectedMachine.Id)/providers/Microsoft.HybridConnectivity/endpoints/default/serviceconfigurations/SSH?api-version=2023-03-15" -Payload '{"properties": {"serviceName": "SSH", "port": 22}}' + } + else { + Write-Output "SSH already enabled on $($connectedMachine.Name)" + } + } # Removing the LogonScript Scheduled Task so it won't run on next reboot @@ -471,22 +526,70 @@ if ($Env:flavor -ne "DevOps") { } } -# Executing the deployment logs bundle PowerShell script in a new window -Write-Header "Uploading Log Bundle" -Invoke-Expression 'cmd /c start Powershell -Command { -$RandomString = -join ((48..57) + (97..122) | Get-Random -Count 6 | % {[char]$_}) -Write-Host "Sleeping for 5 seconds before creating deployment logs bundle..." -Start-Sleep -Seconds 5 -Write-Host "`n" -Write-Host "Creating deployment logs bundle" -7z a $Env:ArcBoxLogsDir\LogsBundle-"$RandomString".zip $Env:ArcBoxLogsDir\*.log -}' - -# Changing to Jumpstart ArcBox wallpaper +#Changing to Jumpstart ArcBox wallpaper Write-Header "Changing wallpaper" -$wallpaperPath = "$Env:ArcBoxDir\wallpaper.png" -Set-JSDesktopBackground -ImagePath $wallpaperPath +# bmp file is required for BGInfo +Convert-JSImageToBitMap -SourceFilePath "$Env:ArcBoxDir\wallpaper.png" -DestinationFilePath "$Env:ArcBoxDir\wallpaper.bmp" + +Set-JSDesktopBackground -ImagePath "$Env:ArcBoxDir\wallpaper.bmp" + +Write-Header "Running tests to verify infrastructure" + +Invoke-Pester -Path "$Env:ArcBoxTestsDir\common.tests.ps1" -Output Detailed -PassThru -OutVariable tests_common +$tests_passed = $tests_common.Passed.Count +$tests_failed = $tests_common.Failed.Count + +switch ($env:flavor) { + 'DevOps' { + Invoke-Pester -Path "$Env:ArcBoxTestsDir\devops.tests.ps1" -Output Detailed -PassThru -OutVariable tests_devops + $tests_passed = $tests_passed + $tests_devops.Passed.Count + $tests_failed = $tests_failed + $tests_devops.Failed.Count +} + 'DataOps' { + Invoke-Pester -Path "$Env:ArcBoxTestsDir\dataops.tests.ps1" -Output Detailed -Output Detailed -PassThru -OutVariable tests_dataops + $tests_passed = $tests_passed + $tests_dataops.Passed.Count + $tests_failed = $tests_failed + $tests_dataops.Failed.Count + } + 'ITPro' { + Invoke-Pester -Path "$Env:ArcBoxTestsDir\itpro.tests.ps1" -Output Detailed -PassThru -OutVariable tests_itpro + $tests_passed = $tests_passed + $tests_itpro.Passed.Count + $tests_failed = $tests_failed + $tests_itpro.Failed.Count +} + 'Full' { + Invoke-Pester -Path "$Env:ArcBoxTestsDir\devops.tests.ps1" -Output Detailed -PassThru -OutVariable tests_devops + $tests_passed = $tests_passed + $tests_devops.Passed.Count + $tests_failed = $tests_failed + $tests_devops.Failed.Count + + Invoke-Pester -Path "$Env:ArcBoxTestsDir\dataops.tests.ps1" -Output Detailed -PassThru -OutVariable tests_dataops + $tests_passed = $tests_passed + $tests_dataops.Passed.Count + $tests_failed = $tests_failed + $tests_dataops.Failed.Count + + Invoke-Pester -Path "$Env:ArcBoxTestsDir\itpro.tests.ps1" -Output Detailed -PassThru -OutVariable tests_itpro + $tests_passed = $tests_passed + $tests_itpro.Passed.Count + $tests_failed = $tests_failed + $tests_itpro.Failed.Count + } +} + +Write-Output "Tests succeeded: $tests_passed" +Write-Output "Tests failed: $tests_failed" + +Write-Header "Adding deployment test results to wallpaper using BGInfo" + +Set-Content "$Env:windir\TEMP\arcbox-tests-succeeded.txt" $tests_passed +Set-Content "$Env:windir\TEMP\arcbox-tests-failed.txt" $tests_failed + +bginfo.exe $Env:ArcBoxTestsDir\arcbox-bginfo.bgi /timer:0 /NOLICPROMPT + +Write-Header "Creating deployment logs bundle" + +$RandomString = -join ((48..57) + (97..122) | Get-Random -Count 6 | % {[char]$_}) +$LogsBundleTempDirectory = "$Env:windir\TEMP\LogsBundle-$RandomString" +$null = New-Item -Path $LogsBundleTempDirectory -ItemType Directory -Force + +#required to avoid "file is being used by another process" error when compressing the logs +Copy-Item -Path "$Env:ArcBoxLogsDir\*.log" -Destination $LogsBundleTempDirectory -Force -PassThru +Compress-Archive -Path "$LogsBundleTempDirectory\*.log" -DestinationPath "$Env:ArcBoxLogsDir\LogsBundle-$RandomString.zip" -PassThru Stop-Transcript diff --git a/azure_jumpstart_arcbox/artifacts/Bootstrap.ps1 b/azure_jumpstart_arcbox/artifacts/Bootstrap.ps1 index 7be525f3de..c4b26a4e3e 100644 --- a/azure_jumpstart_arcbox/artifacts/Bootstrap.ps1 +++ b/azure_jumpstart_arcbox/artifacts/Bootstrap.ps1 @@ -81,6 +81,7 @@ $Env:ArcBoxKVDir = "$Env:ArcBoxDir\KeyVault" $Env:ArcBoxGitOpsDir = "$Env:ArcBoxDir\GitOps" $Env:ArcBoxIconDir = "$Env:ArcBoxDir\Icons" $Env:agentScript = "$Env:ArcBoxDir\agentScript" +$Env:ArcBoxTestsDir = "$Env:ArcBoxDir\Tests" $Env:ToolsDir = "C:\Tools" $Env:tempDir = "C:\Temp" $Env:ArcBoxDataOpsDir = "$Env:ArcBoxDir\DataOps" @@ -96,6 +97,7 @@ New-Item -Path $Env:ToolsDir -ItemType Directory -Force New-Item -Path $Env:tempDir -ItemType directory -Force New-Item -Path $Env:agentScript -ItemType directory -Force New-Item -Path $Env:ArcBoxDataOpsDir -ItemType directory -Force +New-Item -Path $Env:ArcBoxTestsDir -ItemType directory -Force Start-Transcript -Path $Env:ArcBoxLogsDir\Bootstrap.log @@ -167,6 +169,8 @@ Invoke-WebRequest ($templateBaseUrl + "artifacts/dsc/common.dsc.yml") -OutFile $ Invoke-WebRequest ($templateBaseUrl + "artifacts/dsc/dataops.dsc.yml") -OutFile $Env:ArcBoxDscDir\dataops.dsc.yml Invoke-WebRequest ($templateBaseUrl + "artifacts/dsc/devops.dsc.yml") -OutFile $Env:ArcBoxDscDir\devops.dsc.yml Invoke-WebRequest ($templateBaseUrl + "artifacts/dsc/itpro.dsc.yml") -OutFile $Env:ArcBoxDscDir\itpro.dsc.yml +Invoke-WebRequest ($templateBaseUrl + "artifacts/tests/arcbox-bginfo.bgi") -OutFile $Env:ArcBoxTestsDir\arcbox-bginfo.bgi +Invoke-WebRequest ($templateBaseUrl + "artifacts/tests/common.tests.ps1") -OutFile $Env:ArcBoxTestsDir\common.tests.ps1 Invoke-WebRequest ($templateBaseUrl + "artifacts/WinGet.ps1") -OutFile $Env:ArcBoxDir\WinGet.ps1 Invoke-WebRequest ($templateBaseUrl + "../tests/GHActionDeploy.ps1") -OutFile "$Env:ArcBoxDir\GHActionDeploy.ps1" Invoke-WebRequest ($templateBaseUrl + "../tests/OpenSSHDeploy.ps1") -OutFile "$Env:ArcBoxDir\OpenSSHDeploy.ps1" @@ -200,6 +204,7 @@ if ($flavor -eq "Full" -Or $flavor -eq "ITPro") { Invoke-WebRequest ($templateBaseUrl + "artifacts/ArcSQLManualOnboarding.ps1") -OutFile $Env:ArcBoxDir\ArcSQLManualOnboarding.ps1 Invoke-WebRequest ($templateBaseUrl + "artifacts/installArcAgentSQLUser.ps1") -OutFile $Env:ArcBoxDir\installArcAgentSQLUser.ps1 Invoke-WebRequest ($templateBaseUrl + "artifacts/testDefenderForSQL.ps1") -OutFile $Env:ArcBoxDir\testDefenderForSQL.ps1 + Invoke-WebRequest ($templateBaseUrl + "artifacts/tests/itpro.tests.ps1") -OutFile $Env:ArcBoxTestsDir\itpro.tests.ps1 } # DevOps @@ -215,6 +220,7 @@ if ($flavor -eq "DevOps") { Invoke-WebRequest ($templateBaseUrl + "artifacts/gitops_scripts/ResetBookstore.ps1") -OutFile $Env:ArcBoxGitOpsDir\ResetBookstore.ps1 Invoke-WebRequest ($templateBaseUrl + "artifacts/icons/arc.ico") -OutFile $Env:ArcBoxIconDir\arc.ico Invoke-WebRequest ($templateBaseUrl + "artifacts/icons/bookstore.ico") -OutFile $Env:ArcBoxIconDir\bookstore.ico + Invoke-WebRequest ($templateBaseUrl + "artifacts/tests/devops.tests.ps1") -OutFile $Env:ArcBoxTestsDir\devops.tests.ps1 } # DataOps @@ -240,6 +246,7 @@ if ($flavor -eq "DataOps") { Invoke-WebRequest ($templateBaseUrl + "artifacts/installArcAgent.ps1") -OutFile $Env:ArcBoxDir\agentScript\installArcAgent.ps1 Invoke-WebRequest ($templateBaseUrl + "artifacts/installArcAgentSQLSP.ps1") -OutFile $Env:ArcBoxDir\agentScript\installArcAgentSQLSP.ps1 Invoke-WebRequest ($templateBaseUrl + "artifacts/testDefenderForSQL.ps1") -OutFile $Env:ArcBoxDir\testDefenderForSQL.ps1 + Invoke-WebRequest ($templateBaseUrl + "artifacts/tests/dataops.tests.ps1") -OutFile $Env:ArcBoxTestsDir\dataops.tests.ps1 } # Full diff --git a/azure_jumpstart_arcbox/artifacts/WinGet.ps1 b/azure_jumpstart_arcbox/artifacts/WinGet.ps1 index deea085382..549120bc73 100644 --- a/azure_jumpstart_arcbox/artifacts/WinGet.ps1 +++ b/azure_jumpstart_arcbox/artifacts/WinGet.ps1 @@ -9,6 +9,7 @@ Start-Transcript -Path $logFilePath -Force -ErrorAction SilentlyContinue Install-PSResource -Name Microsoft.WinGet.DSC -Scope AllUsers -Quiet -AcceptLicense -TrustRepository -Prerelease # Install DSC resources required for ArcBox +Install-PSResource -Name DSCR_Font -Scope AllUsers -Quiet -AcceptLicense -TrustRepository Install-PSResource -Name HyperVDsc -Scope AllUsers -Quiet -AcceptLicense -TrustRepository -Prerelease # Install WinGet CLI @@ -16,6 +17,11 @@ $null = Repair-WinGetPackageManager -AllUsers Write-Header 'Installing WinGet packages and DSC configurations' $winget = Join-Path -Path $env:LOCALAPPDATA -ChildPath Microsoft\WindowsApps\winget.exe + +# Windows Terminal needs to be installed per user, while WinGet Configuration runs as SYSTEM. Hence, this package is installed in the logon script. +& $winget install Microsoft.WindowsTerminal --version 1.18.3181.0 -s winget + +# Apply WinGet Configuration files & $winget configure --file C:\ArcBox\DSC\common.dsc.yml --accept-configuration-agreements --disable-interactivity switch ($env:flavor) { diff --git a/azure_jumpstart_arcbox/artifacts/dsc/common.dsc.yml b/azure_jumpstart_arcbox/artifacts/dsc/common.dsc.yml index 1e6479c354..3e21650827 100644 --- a/azure_jumpstart_arcbox/artifacts/dsc/common.dsc.yml +++ b/azure_jumpstart_arcbox/artifacts/dsc/common.dsc.yml @@ -6,7 +6,6 @@ properties: id: git directives: description: Install Git - allowPrerelease: true settings: id: Git.Git source: winget @@ -14,7 +13,6 @@ properties: id: vscode directives: description: Install Visual Studio Code - allowPrerelease: true settings: id: Microsoft.VisualStudioCode source: winget @@ -22,7 +20,6 @@ properties: id: AzureCLI directives: description: Install Azure CLI - allowPrerelease: true settings: id: Microsoft.AzureCLI source: winget @@ -30,7 +27,6 @@ properties: id: PowerShell7 directives: description: Install PowerShell 7 - allowPrerelease: true settings: id: Microsoft.PowerShell source: winget @@ -38,7 +34,6 @@ properties: id: kubectl directives: description: Install kubectl - allowPrerelease: true settings: id: Kubernetes.kubectl source: winget @@ -46,7 +41,6 @@ properties: id: edge directives: description: Install Microsoft Edge - allowPrerelease: true settings: id: Microsoft.Edge source: winget @@ -54,7 +48,6 @@ properties: id: azcopy directives: description: Install azcopy - allowPrerelease: true settings: id: Microsoft.Azure.AZCopy.10 source: winget @@ -62,7 +55,6 @@ properties: id: DotNetSDK7 directives: description: Install Microsoft DotNet SDK 7 - allowPrerelease: true settings: id: Microsoft.DotNet.SDK.7 source: winget @@ -70,7 +62,6 @@ properties: id: helm directives: description: Install Helm - allowPrerelease: true settings: id: Helm.Helm source: winget @@ -78,7 +69,6 @@ properties: id: Microsoft.Sysinternals.BGInfo directives: description: Install Sysinternals BGInfo - allowPrerelease: true settings: id: Microsoft.Sysinternals.BGInfo source: winget @@ -86,10 +76,16 @@ properties: id: OpenSSL directives: description: Install OpenSSL - allowPrerelease: true settings: id: FireDaemon.OpenSSL source: winget + - resource: DSCR_Font/cFont + id: CascadiaMono + directives: + description: Install font CascadiaMono + settings: + FontName: Cascadia Mono + FontFile: C:\Program Files\WindowsApps\Microsoft.WindowsTerminal_1.18.3181.0_x64__8wekyb3d8bbwe\CascadiaMono.ttf - resource: PSDscResources/WindowsFeature id: Hyper-V directives: diff --git a/azure_jumpstart_arcbox/artifacts/dsc/dataops.dsc.yml b/azure_jumpstart_arcbox/artifacts/dsc/dataops.dsc.yml index 86bd3f2de5..57d3cf9aed 100644 --- a/azure_jumpstart_arcbox/artifacts/dsc/dataops.dsc.yml +++ b/azure_jumpstart_arcbox/artifacts/dsc/dataops.dsc.yml @@ -6,7 +6,6 @@ properties: id: kubectl directives: description: Install kubectl - allowPrerelease: true settings: id: Kubernetes.kubectl source: winget @@ -14,7 +13,6 @@ properties: id: kubectx directives: description: Install kubectx - allowPrerelease: true settings: id: ahmetb.kubectx source: winget @@ -22,7 +20,6 @@ properties: id: DotNetSDK7 directives: description: Install Microsoft DotNet SDK 7 - allowPrerelease: true settings: id: Microsoft.DotNet.SDK.7 source: winget @@ -30,7 +27,6 @@ properties: id: SQLServerManagementStudio directives: description: Install Microsoft SQL Server Management Studio - allowPrerelease: true settings: id: Microsoft.SQLServerManagementStudio source: winget @@ -38,7 +34,6 @@ properties: id: Microsoft.Azure.DataCLI directives: description: Install Microsoft Azure Data CLI - allowPrerelease: true settings: id: Microsoft.Azure.DataCLI source: winget @@ -46,7 +41,6 @@ properties: id: Microsoft.AzureDataStudio directives: description: Install Microsoft Azure Data Studio - allowPrerelease: true settings: id: Microsoft.AzureDataStudio source: winget diff --git a/azure_jumpstart_arcbox/artifacts/dsc/devops.dsc.yml b/azure_jumpstart_arcbox/artifacts/dsc/devops.dsc.yml index ded57fe8cc..24a479cb3a 100644 --- a/azure_jumpstart_arcbox/artifacts/dsc/devops.dsc.yml +++ b/azure_jumpstart_arcbox/artifacts/dsc/devops.dsc.yml @@ -6,7 +6,6 @@ properties: id: kubectl directives: description: Install kubectl - allowPrerelease: true settings: id: Kubernetes.kubectl source: winget @@ -14,7 +13,6 @@ properties: id: kubectx directives: description: Install kubectx - allowPrerelease: true settings: id: ahmetb.kubectx source: winget @@ -22,7 +20,6 @@ properties: id: DotNetSDK7 directives: description: Install Microsoft DotNet SDK 7 - allowPrerelease: true settings: id: Microsoft.DotNet.SDK.7 source: winget @@ -30,7 +27,6 @@ properties: id: helm directives: description: Install Helm - allowPrerelease: true settings: id: Helm.Helm source: winget diff --git a/azure_jumpstart_arcbox/artifacts/dsc/itpro.dsc.yml b/azure_jumpstart_arcbox/artifacts/dsc/itpro.dsc.yml index ff917f2c8b..a6a2d1014e 100644 --- a/azure_jumpstart_arcbox/artifacts/dsc/itpro.dsc.yml +++ b/azure_jumpstart_arcbox/artifacts/dsc/itpro.dsc.yml @@ -6,7 +6,6 @@ properties: id: terraform directives: description: Install Terraform - allowPrerelease: true settings: id: Hashicorp.Terraform source: winget diff --git a/azure_jumpstart_arcbox/artifacts/powershell/modules/Azure.Arc.Jumpstart.Common/Azure.Arc.Jumpstart.Common.psd1 b/azure_jumpstart_arcbox/artifacts/powershell/modules/Azure.Arc.Jumpstart.Common/Azure.Arc.Jumpstart.Common.psd1 index e81135c294..e02b6b26dc 100644 --- a/azure_jumpstart_arcbox/artifacts/powershell/modules/Azure.Arc.Jumpstart.Common/Azure.Arc.Jumpstart.Common.psd1 +++ b/azure_jumpstart_arcbox/artifacts/powershell/modules/Azure.Arc.Jumpstart.Common/Azure.Arc.Jumpstart.Common.psd1 @@ -12,7 +12,7 @@ RootModule = 'Azure.Arc.Jumpstart.Common.psm1' # Version number of this module. -ModuleVersion = '0.0.1' +ModuleVersion = '0.0.4' # Supported PSEditions # CompatiblePSEditions = @() @@ -69,7 +69,7 @@ Description = 'Common functions for Azure Arc Jumpstart' # NestedModules = @() # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. -FunctionsToExport = 'Set-JSDesktopBackground' +FunctionsToExport = 'Set-JSDesktopBackground','Convert-JSImageToBitMap' # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. CmdletsToExport = '' diff --git a/azure_jumpstart_arcbox/artifacts/powershell/modules/Azure.Arc.Jumpstart.Common/Functions/Public/Convert-JSImageToBitMap.ps1 b/azure_jumpstart_arcbox/artifacts/powershell/modules/Azure.Arc.Jumpstart.Common/Functions/Public/Convert-JSImageToBitMap.ps1 new file mode 100644 index 0000000000..bbcf65126b --- /dev/null +++ b/azure_jumpstart_arcbox/artifacts/powershell/modules/Azure.Arc.Jumpstart.Common/Functions/Public/Convert-JSImageToBitMap.ps1 @@ -0,0 +1,10 @@ +function Convert-JSImageToBitMap { + param ( + $SourceFilePath, + $DestinationFilePath + ) + [Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null + $file = Get-Item $SourceFilePath + $convertfile = new-object System.Drawing.Bitmap($file.Fullname) + $convertfile.Save($DestinationFilePath, "bmp") +} \ No newline at end of file diff --git a/azure_jumpstart_arcbox/artifacts/tests/arcbox-bginfo.bgi b/azure_jumpstart_arcbox/artifacts/tests/arcbox-bginfo.bgi new file mode 100644 index 0000000000..cbfeba7c82 Binary files /dev/null and b/azure_jumpstart_arcbox/artifacts/tests/arcbox-bginfo.bgi differ diff --git a/azure_jumpstart_arcbox/artifacts/tests/common.tests.ps1 b/azure_jumpstart_arcbox/artifacts/tests/common.tests.ps1 new file mode 100644 index 0000000000..176292d6c5 --- /dev/null +++ b/azure_jumpstart_arcbox/artifacts/tests/common.tests.ps1 @@ -0,0 +1,15 @@ +BeforeDiscovery { + $spnpassword = ConvertTo-SecureString $env:spnClientSecret -AsPlainText -Force + $spncredential = New-Object System.Management.Automation.PSCredential ($env:spnClientId, $spnpassword) + + $null = Connect-AzAccount -ServicePrincipal -Credential $spncredential -Tenant $env:spntenantId -Subscription $env:subscriptionId +} + +Describe "ArcBox resource group" { + BeforeAll { + $ResourceGroupName = $env:resourceGroup + } + It "should have 30 resources or more" { + (Get-AzResource -ResourceGroupName $ResourceGroupName).count | Should -BeGreaterOrEqual 30 + } +} diff --git a/azure_jumpstart_arcbox/artifacts/tests/dataops.tests.ps1 b/azure_jumpstart_arcbox/artifacts/tests/dataops.tests.ps1 new file mode 100644 index 0000000000..e69de29bb2 diff --git a/azure_jumpstart_arcbox/artifacts/tests/devops.tests.ps1 b/azure_jumpstart_arcbox/artifacts/tests/devops.tests.ps1 new file mode 100644 index 0000000000..e69de29bb2 diff --git a/azure_jumpstart_arcbox/artifacts/tests/itpro.tests.ps1 b/azure_jumpstart_arcbox/artifacts/tests/itpro.tests.ps1 new file mode 100644 index 0000000000..d2b4ec7287 --- /dev/null +++ b/azure_jumpstart_arcbox/artifacts/tests/itpro.tests.ps1 @@ -0,0 +1,33 @@ + +BeforeDiscovery { + $VMs = @("ArcBox-SQL", "ArcBox-Ubuntu-01", "ArcBox-Ubuntu-02","ArcBox-Win2K19","ArcBox-Win2K22") + + $spnpassword = ConvertTo-SecureString $env:spnClientSecret -AsPlainText -Force + $spncredential = New-Object System.Management.Automation.PSCredential ($env:spnClientId, $spnpassword) + + $null = Connect-AzAccount -ServicePrincipal -Credential $spncredential -Tenant $env:spntenantId -Subscription $env:subscriptionId +} + +# Assert that the Hyper-V virtual machines in $VMs exists, are running and connected as Azure Arc-enabled servers + +Describe "" -ForEach $VMs { + BeforeAll { + $vm = $_ + } + It "VM exists" { + $vmobject = Get-VM -Name $vm + $vmobject | Should -Not -BeNullOrEmpty + } + It "VM is running" { + $vmobject = Get-VM -Name $vm + $vmobject.State | Should -Be "Running" + } + It "Azure Arc Connected Machine exists" { + $connectedMachine = Get-AzConnectedMachine -Name $vm -ResourceGroupName $env:resourceGroup -SubscriptionId $env:subscriptionId + $connectedMachine | Should -Not -BeNullOrEmpty + } + It "Azure Arc Connected Machine is connected" { + $connectedMachine = Get-AzConnectedMachine -Name $vm -ResourceGroupName $env:resourceGroup -SubscriptionId $env:subscriptionId + $connectedMachine.Status | Should -Be "Connected" + } +}