azure_arc_servers_jumpstart/artifacts/Bootstrap.ps1 (199 lines of code) (raw):

param ( [string]$adminUsername, [string]$adminPassword, [string]$spnTenantId, [string]$spnAuthority, [string]$subscriptionId, [string]$resourceGroup, [string]$acceptEula, [string]$azureLocation, [string]$stagingStorageAccountName, [string]$workspaceName, [string]$templateBaseUrl, [string]$rdpPort, [string]$sshPort, [string]$changeTrackingDCR, [string]$vmInsightsDCR ) [System.Environment]::SetEnvironmentVariable('adminUsername', $adminUsername, [System.EnvironmentVariableTarget]::Machine) [System.Environment]::SetEnvironmentVariable('spnTenantId', $spnTenantId, [System.EnvironmentVariableTarget]::Machine) [System.Environment]::SetEnvironmentVariable('spnAuthority', $spnAuthority, [System.EnvironmentVariableTarget]::Machine) [System.Environment]::SetEnvironmentVariable('SPN_TENANT_ID', $spnTenantId, [System.EnvironmentVariableTarget]::Machine) [System.Environment]::SetEnvironmentVariable('SPN_AUTHORITY', $spnAuthority, [System.EnvironmentVariableTarget]::Machine) [System.Environment]::SetEnvironmentVariable('resourceGroup', $resourceGroup, [System.EnvironmentVariableTarget]::Machine) [System.Environment]::SetEnvironmentVariable('ACCEPT_EULA', $acceptEula, [System.EnvironmentVariableTarget]::Machine) [System.Environment]::SetEnvironmentVariable('subscriptionId', $subscriptionId, [System.EnvironmentVariableTarget]::Machine) [System.Environment]::SetEnvironmentVariable('azureLocation', $azureLocation, [System.EnvironmentVariableTarget]::Machine) [System.Environment]::SetEnvironmentVariable('stagingStorageAccountName', $stagingStorageAccountName, [System.EnvironmentVariableTarget]::Machine) [System.Environment]::SetEnvironmentVariable('workspaceName', $workspaceName, [System.EnvironmentVariableTarget]::Machine) [System.Environment]::SetEnvironmentVariable('templateBaseUrl', $templateBaseUrl, [System.EnvironmentVariableTarget]::Machine) [System.Environment]::SetEnvironmentVariable('automationTriggerAtLogon', $automationTriggerAtLogon, [System.EnvironmentVariableTarget]::Machine) [System.Environment]::SetEnvironmentVariable('ArcBoxDir', "C:\ArcBox", [System.EnvironmentVariableTarget]::Machine) [System.Environment]::SetEnvironmentVariable('changeTrackingDCR', $changeTrackingDCR, [System.EnvironmentVariableTarget]::Machine) [System.Environment]::SetEnvironmentVariable('vmInsightsDCR', $vmInsightsDCR, [System.EnvironmentVariableTarget]::Machine) [System.Environment]::SetEnvironmentVariable('ErrorActionPreference', "Continue", [System.EnvironmentVariableTarget]::Machine) # Formatting VMs disk $disk = (Get-Disk | Where-Object partitionstyle -eq 'raw')[0] $driveLetter = "F" $label = "VMsDisk" $disk | Initialize-Disk -PartitionStyle MBR -PassThru | ` New-Partition -UseMaximumSize -DriveLetter $driveLetter | ` Format-Volume -FileSystem NTFS -NewFileSystemLabel $label -Confirm:$false -Force # Creating ArcBox path Write-Output "Creating ArcBox path" $Env:ArcBoxDir = "C:\ArcBox" $Env:ArcBoxDscDir = "$Env:ArcBoxDir\DSC" $Env:ArcBoxLogsDir = "$Env:ArcBoxDir\Logs" $Env:ArcBoxVMDir = "F:\Virtual Machines" $Env:ArcBoxKVDir = "$Env:ArcBoxDir\KeyVault" $Env:ArcBoxIconDir = "$Env:ArcBoxDir\Icons" $Env:agentScript = "$Env:ArcBoxDir\agentScript" $Env:ToolsDir = "C:\Tools" $Env:tempDir = "C:\Temp" New-Item -Path $Env:ArcBoxDir -ItemType directory -Force New-Item -Path $Env:ArcBoxDscDir -ItemType directory -Force New-Item -Path $Env:ArcBoxLogsDir -ItemType directory -Force New-Item -Path $Env:ArcBoxVMDir -ItemType directory -Force New-Item -Path $Env:ArcBoxKVDir -ItemType directory -Force New-Item -Path $Env:ArcBoxIconDir -ItemType directory -Force New-Item -Path $Env:ToolsDir -ItemType Directory -Force New-Item -Path $Env:tempDir -ItemType directory -Force New-Item -Path $Env:agentScript -ItemType directory -Force Start-Transcript -Path $Env:ArcBoxLogsDir\Bootstrap.log $ErrorActionPreference = 'SilentlyContinue' #if ([bool]$vmAutologon) { Write-Host "Configuring VM Autologon" Set-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" "AutoAdminLogon" "1" Set-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" "DefaultUserName" $adminUsername Set-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" "DefaultPassword" $adminPassword #} # Copy PowerShell Profile and Reload Invoke-WebRequest ($templateBaseUrl + "artifacts/PSProfile.ps1") -OutFile $PsHome\Profile.ps1 .$PsHome\Profile.ps1 # Extending C:\ partition to the maximum size Write-Host "Extending C:\ partition to the maximum size" Resize-Partition -DriveLetter C -Size $(Get-PartitionSupportedSize -DriveLetter C).SizeMax # Installing Posh-SSH PowerShell Module Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force #Install-Module -Name Posh-SSH -Force Install-Module -Name Microsoft.PowerShell.PSResourceGet -Force -Scope AllUsers #$modules = @("Az", "Az.ConnectedMachine", "Microsoft.PowerShell.SecretManagement", "Posh-SSH", "Pester") $modules = @("Az", "Az.ConnectedMachine", "Microsoft.PowerShell.SecretManagement","Azure.Arc.Jumpstart.Common", "Pester") foreach ($module in $modules) { # Write-Output "Installing module $module" Install-PSResource -Name $module -Scope AllUsers -Quiet -AcceptLicense -TrustRepository } # Installing DHCP service Write-Output "Installing DHCP service" Install-WindowsFeature -Name "DHCP" -IncludeManagementTools # Installing tools Write-Header "Installing PowerShell 7" $ProgressPreference = 'SilentlyContinue' $url = "https://github.com/PowerShell/PowerShell/releases/latest" $latestVersion = (Invoke-WebRequest -UseBasicParsing -Uri $url).Content | Select-String -Pattern "v[0-9]+\.[0-9]+\.[0-9]+" | Select-Object -ExpandProperty Matches | Select-Object -ExpandProperty Value $downloadUrl = "https://github.com/PowerShell/PowerShell/releases/download/$latestVersion/PowerShell-$($latestVersion.Substring(1,5))-win-x64.msi" Invoke-WebRequest -UseBasicParsing -Uri $downloadUrl -OutFile .\PowerShell7.msi Start-Process msiexec.exe -Wait -ArgumentList '/I PowerShell7.msi /quiet ADD_EXPLORER_CONTEXT_MENU_OPENPOWERSHELL=1 ADD_FILE_CONTEXT_MENU_RUNPOWERSHELL=1 ENABLE_PSREMOTING=1 REGISTER_MANIFEST=1 USE_MU=1 ENABLE_MU=1 ADD_PATH=1' Remove-Item .\PowerShell7.msi Copy-Item $PsHome\Profile.ps1 -Destination "C:\Program Files\PowerShell\7\" Write-Header "Fetching GitHub Artifacts" # All flavors Write-Host "Fetching Artifacts for All Flavors" Invoke-WebRequest "https://raw.githubusercontent.com/azure/arc_jumpstart_docs/main/img/wallpaper/arcbox_wallpaper_dark.png" -OutFile $Env:ArcBoxDir\wallpaper.png Invoke-WebRequest ($templateBaseUrl + "artifacts/MonitorWorkbookLogonScript.ps1") -OutFile $Env:ArcBoxDir\MonitorWorkbookLogonScript.ps1 Invoke-WebRequest ($templateBaseUrl + "artifacts/mgmtMonitorWorkbook.parameters.json") -OutFile $Env:ArcBoxDir\mgmtMonitorWorkbook.parameters.json Invoke-WebRequest ($templateBaseUrl + "artifacts/monitoring/arc-inventory-workbook.json") -OutFile "$Env:ArcBoxDir\arc-inventory-workbook.json" Invoke-WebRequest ($templateBaseUrl + "artifacts/monitoring/arc-osperformance-workbook.json") -OutFile "$Env:ArcBoxDir\arc-osperformance-workbook.json" Invoke-WebRequest ($templateBaseUrl + "artifacts/DeploymentStatus.ps1") -OutFile $Env:ArcBoxDir\DeploymentStatus.ps1 Invoke-WebRequest ($templateBaseUrl + "artifacts/LogInstructions.txt") -OutFile $Env:ArcBoxLogsDir\LogInstructions.txt Invoke-WebRequest ($templateBaseUrl + "artifacts/dsc/common.dsc.yml") -OutFile $Env:ArcBoxDscDir\common.dsc.yml #Invoke-WebRequest ($templateBaseUrl + "artifacts/dsc/virtual_machines_sql.dsc.yml") -OutFile $Env:ArcBoxDscDir\virtual_machines_sql.dsc.yml Invoke-WebRequest ($templateBaseUrl + "artifacts/WinGet.ps1") -OutFile $Env:ArcBoxDir\WinGet.ps1 Invoke-WebRequest ($templateBaseUrl + "artifacts/squid.conf") -OutFile $Env:ArcBoxDir\squid.conf Invoke-WebRequest ($templateBaseUrl + "artifacts/whitelist.txt") -OutFile $Env:ArcBoxDir\whitelist.txt Invoke-WebRequest ($templateBaseUrl + "artifacts/ct.txt") -OutFile $Env:ArcBoxDir\ct.txt # Workbook template Invoke-WebRequest ($templateBaseUrl + "artifacts/mgmtMonitorWorkbookITPro.json") -OutFile $Env:ArcBoxDir\mgmtMonitorWorkbook.json Write-Host "Fetching Artifacts" Invoke-WebRequest ($templateBaseUrl + "artifacts/ArcServersLogonScript.ps1") -OutFile $Env:ArcBoxDir\ArcServersLogonScript.ps1 Invoke-WebRequest ($templateBaseUrl + "artifacts/installArcAgent.ps1") -OutFile $Env:ArcBoxDir\agentScript\installArcAgent.ps1 Invoke-WebRequest ($templateBaseUrl + "artifacts/installArcAgentUbuntu.sh") -OutFile $Env:ArcBoxDir\agentScript\installArcAgentUbuntu.sh Invoke-WebRequest ($templateBaseUrl + "artifacts/testDefenderForServers.cmd") -OutFile $Env:ArcBoxDir\agentScript\testDefenderForServers.cmd Invoke-WebRequest ($templateBaseUrl + "artifacts/InstallArcSQLExtensionAtScale.ps1") -OutFile $Env:ArcBoxDir\InstallArcSQLExtensionAtScale.ps1 Invoke-WebRequest ($templateBaseUrl + "artifacts/testDefenderForSQL.ps1") -OutFile $Env:ArcBoxDir\testDefenderForSQL.ps1 Invoke-WebRequest ($templateBaseUrl + "artifacts/SqlAdvancedThreatProtectionShell.psm1") -OutFile $Env:ArcBoxDir\SqlAdvancedThreatProtectionShell.psm1 Invoke-WebRequest "https://github.com/PowerShell/PowerShell/releases/download/v7.4.1/PowerShell-7.4.1-win-x64.msi" -OutFile $Env:ArcBoxDir\PowerShell-7.4.1-win-x64.msi Invoke-WebRequest ($templateBaseUrl + "artifacts/AdventureWorksLT2019.bak") -OutFile "$Env:ArcBoxDir\AdventureWorksLT2019.bak" Invoke-WebRequest ($templateBaseUrl + "artifacts/dsc/itpro.dsc.yml") -OutFile $Env:ArcBoxDscDir\itpro.dsc.yml Invoke-WebRequest ($templateBaseUrl + "artifacts/dsc/virtual_machines_itpro.dsc.yml") -OutFile $Env:ArcBoxDscDir\virtual_machines_itpro.dsc.yml # Disable Microsoft Edge sidebar $RegistryPath = 'HKLM:\SOFTWARE\Policies\Microsoft\Edge' $Name = 'HubsSidebarEnabled' $Value = '00000000' # Create the key if it does not exist If (-NOT (Test-Path $RegistryPath)) { New-Item -Path $RegistryPath -Force | Out-Null } New-ItemProperty -Path $RegistryPath -Name $Name -Value $Value -PropertyType DWORD -Force # Disable Microsoft Edge first-run Welcome screen $RegistryPath = 'HKLM:\SOFTWARE\Policies\Microsoft\Edge' $Name = 'HideFirstRunExperience' $Value = '00000001' # Create the key if it does not exist If (-NOT (Test-Path $RegistryPath)) { New-Item -Path $RegistryPath -Force | Out-Null } New-ItemProperty -Path $RegistryPath -Name $Name -Value $Value -PropertyType DWORD -Force # Change RDP Port Write-Host "RDP port number from configuration is $rdpPort" if (($rdpPort -ne $null) -and ($rdpPort -ne "") -and ($rdpPort -ne "3389")) { Write-Host "Configuring RDP port number to $rdpPort" $TSPath = 'HKLM:\SYSTEM\CurrentControlSet\Control\Terminal Server' $RDPTCPpath = $TSPath + '\Winstations\RDP-Tcp' Set-ItemProperty -Path $TSPath -name 'fDenyTSConnections' -Value 0 # RDP port $portNumber = (Get-ItemProperty -Path $RDPTCPpath -Name 'PortNumber').PortNumber Write-Host "Current RDP PortNumber: $portNumber" if (!($portNumber -eq $rdpPort)) { Write-Host Setting RDP PortNumber to $rdpPort Set-ItemProperty -Path $RDPTCPpath -name 'PortNumber' -Value $rdpPort Restart-Service TermService -force } #Setup firewall rules if ($rdpPort -eq 3389) { netsh advfirewall firewall set rule group="remote desktop" new Enable=Yes } else { $systemroot = get-content env:systemroot netsh advfirewall firewall add rule name="Remote Desktop - Custom Port" dir=in program=$systemroot\system32\svchost.exe service=termservice action=allow protocol=TCP localport=$RDPPort enable=yes } Write-Host "RDP port configuration complete." } Write-Header "Configuring Logon Scripts" $ScheduledTaskExecutable = "pwsh.exe" # Creating scheduled task for MonitorWorkbookLogonScript.ps1 # Creating scheduled task for WinGet.ps1 $Trigger = New-ScheduledTaskTrigger -AtLogOn $Action = New-ScheduledTaskAction -Execute $ScheduledTaskExecutable -Argument $Env:ArcBoxDir\WinGet.ps1 Register-ScheduledTask -TaskName "WinGetLogonScript" -Trigger $Trigger -User $adminUsername -Action $Action -RunLevel "Highest" -Force # Creating scheduled task for ArcServersLogonScript.ps1 $Action = New-ScheduledTaskAction -Execute $ScheduledTaskExecutable -Argument $Env:ArcBoxDir\ArcServersLogonScript.ps1 Register-ScheduledTask -TaskName "ArcServersLogonScript" -User $adminUsername -Action $Action -RunLevel "Highest" -Force $Trigger = New-ScheduledTaskTrigger -AtLogOn $Action = New-ScheduledTaskAction -Execute "pwsh.exe" -Argument $Env:ArcBoxDir\MonitorWorkbookLogonScript.ps1 Register-ScheduledTask -TaskName "MonitorWorkbookLogonScript" -Trigger $Trigger -User $adminUsername -Action $Action -RunLevel "Highest" -Force # Disabling Windows Server Manager Scheduled Task Get-ScheduledTask -TaskName ServerManager | Disable-ScheduledTask Write-Header "Installing Hyper-V" # Install Hyper-V and reboot Write-Host "Installing Hyper-V and restart" Enable-WindowsOptionalFeature -Online -FeatureName Containers -All -NoRestart Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform -NoRestart Install-WindowsFeature -Name Hyper-V -IncludeAllSubFeature -IncludeManagementTools -Restart # Clean up Bootstrap.log Write-Host "Clean up Bootstrap.log" Stop-Transcript $logSuppress = Get-Content $Env:ArcBoxLogsDir\Bootstrap.log | Where-Object { $_ -notmatch "Host Application: powershell.exe" } $logSuppress | Set-Content $Env:ArcBoxLogsDir\Bootstrap.log -Force # Restart computer Restart-Computer