зеркало из https://github.com/Azure/missionlz.git
Add-On Imaging: Improvements, Bug Fixes, and Software Bundler (#1063)
* Fixes * updated some logic * moved $Path around * fixed default value for update service * Updates and fixes to customizations and bundle ps1 --------- Co-authored-by: Jason Masten <jamasten@microsoft.com>
This commit is contained in:
Родитель
c35513e209
Коммит
deb948cd4d
|
@ -23,6 +23,7 @@ param excludeFromLatest bool
|
||||||
param hybridUseBenefit bool
|
param hybridUseBenefit bool
|
||||||
param imageDefinitionName string
|
param imageDefinitionName string
|
||||||
param imageMajorVersion int
|
param imageMajorVersion int
|
||||||
|
param imageMinorVersion int
|
||||||
param imagePatchVersion int
|
param imagePatchVersion int
|
||||||
param imageVirtualMachineName string
|
param imageVirtualMachineName string
|
||||||
param installAccess bool
|
param installAccess bool
|
||||||
|
@ -84,6 +85,7 @@ var parameters = {
|
||||||
hybridUseBenefit: hybridUseBenefit
|
hybridUseBenefit: hybridUseBenefit
|
||||||
imageDefinitionName: imageDefinitionName
|
imageDefinitionName: imageDefinitionName
|
||||||
imageMajorVersion: string(imageMajorVersion)
|
imageMajorVersion: string(imageMajorVersion)
|
||||||
|
imageMinorVersion: string(imageMinorVersion)
|
||||||
imagePatchVersion: string(imagePatchVersion)
|
imagePatchVersion: string(imagePatchVersion)
|
||||||
imageVirtualMachineName: imageVirtualMachineName
|
imageVirtualMachineName: imageVirtualMachineName
|
||||||
installAccess: string(installAccess)
|
installAccess: string(installAccess)
|
||||||
|
|
|
@ -24,6 +24,7 @@ param excludeFromLatest bool
|
||||||
param hybridUseBenefit bool
|
param hybridUseBenefit bool
|
||||||
param imageDefinitionName string
|
param imageDefinitionName string
|
||||||
param imageMajorVersion int
|
param imageMajorVersion int
|
||||||
|
param imageMinorVersion int
|
||||||
param imagePatchVersion int
|
param imagePatchVersion int
|
||||||
param imageVirtualMachineName string
|
param imageVirtualMachineName string
|
||||||
param installAccess bool
|
param installAccess bool
|
||||||
|
@ -149,6 +150,7 @@ module managementVM 'managementVM.bicep' = {
|
||||||
|
|
||||||
userAssignedIdentityResourceId: userAssignedIdentityResourceId
|
userAssignedIdentityResourceId: userAssignedIdentityResourceId
|
||||||
virtualMachineName: managementVirtualMachineName
|
virtualMachineName: managementVirtualMachineName
|
||||||
|
virtualMachineSize: virtualMachineSize
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,6 +177,7 @@ module automationAccount 'automationAccount.bicep' = {
|
||||||
hybridUseBenefit: hybridUseBenefit
|
hybridUseBenefit: hybridUseBenefit
|
||||||
imageDefinitionName: imageDefinitionName
|
imageDefinitionName: imageDefinitionName
|
||||||
imageMajorVersion: imageMajorVersion
|
imageMajorVersion: imageMajorVersion
|
||||||
|
imageMinorVersion: imageMinorVersion
|
||||||
imagePatchVersion: imagePatchVersion
|
imagePatchVersion: imagePatchVersion
|
||||||
imageVirtualMachineName: imageVirtualMachineName
|
imageVirtualMachineName: imageVirtualMachineName
|
||||||
installAccess: installAccess
|
installAccess: installAccess
|
||||||
|
|
|
@ -37,7 +37,7 @@ param virtualMachineName string
|
||||||
|
|
||||||
var installAccessVar = '${installAccess}installAccess'
|
var installAccessVar = '${installAccess}installAccess'
|
||||||
var installers = customizations
|
var installers = customizations
|
||||||
var installExcelVar = '${installExcel}installWord'
|
var installExcelVar = '${installExcel}installExcel'
|
||||||
var installOneDriveVar = '${installOneDrive}installOneDrive'
|
var installOneDriveVar = '${installOneDrive}installOneDrive'
|
||||||
var installOneNoteVar = '${installOneNote}installOneNote'
|
var installOneNoteVar = '${installOneNote}installOneNote'
|
||||||
var installOutlookVar = '${installOutlook}installOutlook'
|
var installOutlookVar = '${installOutlook}installOutlook'
|
||||||
|
@ -54,7 +54,7 @@ resource virtualMachine 'Microsoft.Compute/virtualMachines@2022-11-01' existing
|
||||||
|
|
||||||
@batchSize(1)
|
@batchSize(1)
|
||||||
resource applications 'Microsoft.Compute/virtualMachines/runCommands@2023-03-01' = [
|
resource applications 'Microsoft.Compute/virtualMachines/runCommands@2023-03-01' = [
|
||||||
for installer in installers: {
|
for installer in installers: if (installer.enabled) {
|
||||||
parent: virtualMachine
|
parent: virtualMachine
|
||||||
name: 'app-${installer.name}'
|
name: 'app-${installer.name}'
|
||||||
location: location
|
location: location
|
||||||
|
@ -111,18 +111,46 @@ resource applications 'Microsoft.Compute/virtualMachines/runCommands@2023-03-01'
|
||||||
$StorageAccountUrl = "https://" + $StorageAccountName + ".blob." + $StorageEndpoint + "/"
|
$StorageAccountUrl = "https://" + $StorageAccountName + ".blob." + $StorageEndpoint + "/"
|
||||||
$TokenUri = "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=$StorageAccountUrl&object_id=$UserAssignedIdentityObjectId"
|
$TokenUri = "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=$StorageAccountUrl&object_id=$UserAssignedIdentityObjectId"
|
||||||
$AccessToken = ((Invoke-WebRequest -Headers @{Metadata=$true} -Uri $TokenUri -UseBasicParsing).Content | ConvertFrom-Json).access_token
|
$AccessToken = ((Invoke-WebRequest -Headers @{Metadata=$true} -Uri $TokenUri -UseBasicParsing).Content | ConvertFrom-Json).access_token
|
||||||
|
$BlobFileName = $BlobName.Split("/")[-1]
|
||||||
New-Item -Path $env:windir\temp -Name $Installer -ItemType "directory" -Force
|
New-Item -Path $env:windir\temp -Name $Installer -ItemType "directory" -Force
|
||||||
New-Item -Path $env:windir\temp\$Installer -Name 'Files' -ItemType "directory" -Force
|
$InstallerDirectory = "$env:windir\temp\$Installer"
|
||||||
|
Write-Host "Setting file copy to install directory: $InstallerDirectory"
|
||||||
|
Set-Location -Path $InstallerDirectory
|
||||||
|
Write-Host "Invoking WebClient download for file : $BlobFileName"
|
||||||
#Invoking WebClient to download blobs because it is more efficient than Invoke-WebRequest for large files.
|
#Invoking WebClient to download blobs because it is more efficient than Invoke-WebRequest for large files.
|
||||||
$WebClient = New-Object System.Net.WebClient
|
$WebClient = New-Object System.Net.WebClient
|
||||||
$WebClient.Headers.Add('x-ms-version', '2017-11-09')
|
$WebClient.Headers.Add('x-ms-version', '2017-11-09')
|
||||||
$webClient.Headers.Add("Authorization", "Bearer $AccessToken")
|
$webClient.Headers.Add("Authorization", "Bearer $AccessToken")
|
||||||
$webClient.DownloadFile("$StorageAccountUrl$ContainerName/$BlobName", "$env:windir\temp\$Installer\Files\$Blobname")
|
$webClient.DownloadFile("$StorageAccountUrl$ContainerName/$BlobName", "$InstallerDirectory\$BlobName")
|
||||||
Start-Sleep -Seconds 30
|
Start-Sleep -Seconds 30
|
||||||
Set-Location -Path $env:windir\temp\$Installer
|
$Path = (Get-ChildItem -Path "$InstallerDirectory\$BlobName" -Recurse | Where-Object {$_.Name -eq "$BlobName"}).FullName
|
||||||
if($Blobname -like ("*.exe"))
|
if($BlobName -like ("*.exe"))
|
||||||
{
|
{
|
||||||
Start-Process -FilePath $env:windir\temp\$Installer\Files\$Blobname -ArgumentList $Arguments -NoNewWindow -Wait -PassThru
|
Start-Process -FilePath $InstallerDirectory\$BlobName -ArgumentList $Arguments -NoNewWindow -Wait -PassThru
|
||||||
|
$wmistatus = Get-WmiObject -Class Win32_Product | Where-Object Name -like "*$($Installer)*"
|
||||||
|
if($wmistatus)
|
||||||
|
{
|
||||||
|
Write-Host $wmistatus.Name "is installed"
|
||||||
|
}
|
||||||
|
$regstatus = Get-ItemProperty 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*' | Where-Object { $_.DisplayName -like "*$($Installer)*" }
|
||||||
|
if($regstatus)
|
||||||
|
{
|
||||||
|
Write-Host $regstatus.DisplayName "is installed"
|
||||||
|
}
|
||||||
|
$regstatusWow6432 = Get-ItemProperty 'HKLM:\Software\WOW6432Node\*' | Where-Object { $_.PSChildName -like "*$($Installer)*" }
|
||||||
|
if($regstatusWow6432)
|
||||||
|
{
|
||||||
|
Write-Host $regstatusWow6432.PSChildName "is installed"
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Write-host $Installer "did not install properly, please check arguments"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if($BlobName -like ("*.msi"))
|
||||||
|
{
|
||||||
|
Write-Host "Invoking msiexec.exe for install path : $Path"
|
||||||
|
Start-Process -FilePath msiexec.exe -ArgumentList "/i $Path $Arguments" -Wait
|
||||||
$status = Get-WmiObject -Class Win32_Product | Where-Object Name -like "*$($installer)*"
|
$status = Get-WmiObject -Class Win32_Product | Where-Object Name -like "*$($installer)*"
|
||||||
if($status)
|
if($status)
|
||||||
{
|
{
|
||||||
|
@ -133,36 +161,29 @@ resource applications 'Microsoft.Compute/virtualMachines/runCommands@2023-03-01'
|
||||||
Write-host $Installer "did not install properly, please check arguments"
|
Write-host $Installer "did not install properly, please check arguments"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if($Blobname -like ("*.msi"))
|
if($BlobName -like ("*.bat"))
|
||||||
{
|
{
|
||||||
Set-Location -Path $env:windir\temp\$Installer\Files
|
Start-Process -FilePath cmd.exe -ArgumentList $InstallerDirectory\$Arguments -Wait
|
||||||
Start-Process -FilePath msiexec.exe -ArgumentList $Arguments -Wait
|
}
|
||||||
$status = Get-WmiObject -Class Win32_Product | Where-Object Name -like "*$($installer)*"
|
if($BlobName -like ("*.ps1"))
|
||||||
if($status)
|
|
||||||
{
|
{
|
||||||
Write-Host $status.Name "is installed"
|
if($BlobName -like ("Install-BundleSoftware.ps1"))
|
||||||
|
{
|
||||||
|
Start-Process -FilePath PowerShell.exe -ArgumentList "-File $Path -UserAssignedIdentityObjectId $UserAssignedIdentityObjectId -StorageAccountName $StorageAccountName -ContainerName $ContainerName -StorageEndpoint $StorageEndpoint $Arguments" -Wait
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Write-host $Installer "did not install properly, please check arguments"
|
Start-Process -FilePath PowerShell.exe -ArgumentList "-File $Path $Arguments" -Wait
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if($Blobname -like ("*.bat"))
|
if($BlobName -like ("*.zip"))
|
||||||
{
|
{
|
||||||
Start-Process -FilePath cmd.exe -ArgumentList $env:windir\temp\$Installer\Files\$Arguments -Wait
|
Expand-Archive -Path $InstallerDirectory\$BlobName -DestinationPath $InstallerDirectory -Force
|
||||||
}
|
Remove-Item -Path .\$BlobName -Force -Recurse
|
||||||
if($Blobname -like ("*.ps1"))
|
|
||||||
{
|
|
||||||
Start-Process -FilePath PowerShell.exe -ArgumentList $env:windir\temp\$Installer\Files\$Arguments -Wait
|
|
||||||
}
|
|
||||||
if($Blobname -like ("*.zip"))
|
|
||||||
{
|
|
||||||
Set-Location -Path $env:windir\temp\$Installer\Files
|
|
||||||
Expand-Archive -Path $env:windir\temp\$Installer\Files\$Blobname -DestinationPath $env:windir\temp\$Installer\Files -Force
|
|
||||||
Remove-Item -Path .\$Blobname -Force -Recurse
|
|
||||||
}
|
}
|
||||||
Write-Host "Removing $Installer Files"
|
Write-Host "Removing $Installer Files"
|
||||||
Remove-item $env:windir\temp\$Installer -Force -Recurse -Confirm:$false
|
#Start-Sleep -Seconds 5
|
||||||
|
Remove-item $env:windir\temp\$Installer -Force -Recurse -Confirm:$false -ErrorAction SilentlyContinue
|
||||||
'''
|
'''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,6 +17,7 @@ param excludeFromLatest bool = true
|
||||||
param hybridUseBenefit bool = false
|
param hybridUseBenefit bool = false
|
||||||
param imageDefinitionName string
|
param imageDefinitionName string
|
||||||
param imageMajorVersion int
|
param imageMajorVersion int
|
||||||
|
param imageMinorVersion int
|
||||||
param imagePatchVersion int
|
param imagePatchVersion int
|
||||||
param imageVirtualMachineName string
|
param imageVirtualMachineName string
|
||||||
param installAccess bool = false
|
param installAccess bool = false
|
||||||
|
@ -55,7 +56,7 @@ param storageAccountResourceId string
|
||||||
param subnetResourceId string
|
param subnetResourceId string
|
||||||
param tags object = {}
|
param tags object = {}
|
||||||
param teamsInstaller string = ''
|
param teamsInstaller string = ''
|
||||||
param updateService string = 'MicrosoftUpdate'
|
param updateService string = 'MU'
|
||||||
param userAssignedIdentityClientId string
|
param userAssignedIdentityClientId string
|
||||||
param userAssignedIdentityPrincipalId string
|
param userAssignedIdentityPrincipalId string
|
||||||
param userAssignedIdentityResourceId string
|
param userAssignedIdentityResourceId string
|
||||||
|
@ -64,8 +65,7 @@ param vDOTInstaller string = ''
|
||||||
param virtualMachineSize string
|
param virtualMachineSize string
|
||||||
param wsusServer string = ''
|
param wsusServer string = ''
|
||||||
|
|
||||||
var autoImageVersion = '${imageMajorVersion}.${imageSuffix}.${imagePatchVersion}'
|
var autoImageVersion = '${imageMajorVersion}.${imageMinorVersion}.${imagePatchVersion}'
|
||||||
var imageSuffix = take(deploymentNameSuffix, 9)
|
|
||||||
var storageAccountName = split(storageAccountResourceId, '/')[8]
|
var storageAccountName = split(storageAccountResourceId, '/')[8]
|
||||||
var storageEndpoint = environment().suffixes.storage
|
var storageEndpoint = environment().suffixes.storage
|
||||||
var subscriptionId = subscription().subscriptionId
|
var subscriptionId = subscription().subscriptionId
|
||||||
|
@ -91,6 +91,7 @@ module managementVM 'managementVM.bicep' =
|
||||||
tags: tags
|
tags: tags
|
||||||
userAssignedIdentityResourceId: userAssignedIdentityResourceId
|
userAssignedIdentityResourceId: userAssignedIdentityResourceId
|
||||||
virtualMachineName: managementVirtualMachineName
|
virtualMachineName: managementVirtualMachineName
|
||||||
|
virtualMachineSize: virtualMachineSize
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -191,7 +192,7 @@ module microsoftUdpates 'microsoftUpdates.bicep' =
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|
||||||
module restartVirtualMachine2 'restartVirtualMachine.bicep' = {
|
module restartVirtualMachine2 'restartVirtualMachine.bicep' = if (installUpdates) {
|
||||||
name: 'restart-vm-2-${deploymentNameSuffix}'
|
name: 'restart-vm-2-${deploymentNameSuffix}'
|
||||||
scope: resourceGroup(subscriptionId, resourceGroupName)
|
scope: resourceGroup(subscriptionId, resourceGroupName)
|
||||||
params: {
|
params: {
|
||||||
|
|
|
@ -56,7 +56,7 @@ resource keyVault 'Microsoft.KeyVault/vaults@2021-10-01' = {
|
||||||
enabledForTemplateDeployment: true
|
enabledForTemplateDeployment: true
|
||||||
enabledForDiskEncryption: false
|
enabledForDiskEncryption: false
|
||||||
enableRbacAuthorization: true
|
enableRbacAuthorization: true
|
||||||
enableSoftDelete: false
|
enableSoftDelete: true
|
||||||
networkAcls: {
|
networkAcls: {
|
||||||
bypass: 'AzureServices'
|
bypass: 'AzureServices'
|
||||||
defaultAction: 'Deny'
|
defaultAction: 'Deny'
|
||||||
|
|
|
@ -18,6 +18,7 @@ param tags object
|
||||||
//param userAssignedIdentityPrincipalId string
|
//param userAssignedIdentityPrincipalId string
|
||||||
param userAssignedIdentityResourceId string
|
param userAssignedIdentityResourceId string
|
||||||
param virtualMachineName string
|
param virtualMachineName string
|
||||||
|
param virtualMachineSize string
|
||||||
|
|
||||||
resource networkInterface 'Microsoft.Network/networkInterfaces@2023-04-01' = {
|
resource networkInterface 'Microsoft.Network/networkInterfaces@2023-04-01' = {
|
||||||
name: 'nic-${virtualMachineName}'
|
name: 'nic-${virtualMachineName}'
|
||||||
|
@ -53,14 +54,16 @@ resource virtualMachine 'Microsoft.Compute/virtualMachines@2022-03-01' = {
|
||||||
mlzTags
|
mlzTags
|
||||||
)
|
)
|
||||||
identity: {
|
identity: {
|
||||||
type: 'UserAssigned'
|
type: 'SystemAssigned, UserAssigned'
|
||||||
|
//A System Assigned Identity is required for the Hybrid Runbook Worker Extension
|
||||||
|
//https://learn.microsoft.com/en-us/azure/automation/troubleshoot/extension-based-hybrid-runbook-worker#scenario-hybrid-worker-deployment-fails-due-to-system-assigned-identity-not-enabled
|
||||||
userAssignedIdentities: {
|
userAssignedIdentities: {
|
||||||
'${userAssignedIdentityResourceId}': {}
|
'${userAssignedIdentityResourceId}': {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
properties: {
|
properties: {
|
||||||
hardwareProfile: {
|
hardwareProfile: {
|
||||||
vmSize: 'Standard_D2s_v3'
|
vmSize: virtualMachineSize
|
||||||
}
|
}
|
||||||
osProfile: {
|
osProfile: {
|
||||||
computerName: virtualMachineName
|
computerName: virtualMachineName
|
||||||
|
|
|
@ -0,0 +1,134 @@
|
||||||
|
<#
|
||||||
|
.SYNOPSIS
|
||||||
|
This script installs software on an Azure Virtual Machine from a Storage Account.
|
||||||
|
|
||||||
|
.DESCRIPTION
|
||||||
|
The Install-BundleSoftware function installs specified piece of software from a
|
||||||
|
Storage Account. It determines the software installation method by first downloading
|
||||||
|
the software installation file name and parameters from the Bundle Manifest json file.
|
||||||
|
|
||||||
|
.PARAMETER UserAssignedIdentityObjectId
|
||||||
|
Specifies the user Assigned Identity Object Id that is assigned to the virtual machine
|
||||||
|
and has access to the storage account.
|
||||||
|
|
||||||
|
.PARAMETER StorageAccountName
|
||||||
|
Specifies the storage account name where the software installation files are stored.
|
||||||
|
|
||||||
|
.PARAMETER ContainerName
|
||||||
|
Specifies the container in the storage account where the software installation files
|
||||||
|
are stored.
|
||||||
|
|
||||||
|
.PARAMETER StorageEndpoint
|
||||||
|
Specifies the endpoint for the storage account. This changes depending on which cloud
|
||||||
|
the storage account is in. Ex: core.windows.net, core.chinacloudapi.cn, core.cloudapi.de
|
||||||
|
core.usgovcloudapi.net, etc.
|
||||||
|
|
||||||
|
.PARAMETER BundleManifestBlob
|
||||||
|
Specifies the blob name of the Bundle Manifest json file that contains the software
|
||||||
|
installation file names and parameters.
|
||||||
|
|
||||||
|
.EXAMPLE
|
||||||
|
$UserAssignedIdentityObjectId = '00000000-0000-0000-0000-000000000000'
|
||||||
|
$StorageAccountName = 'myStorageAccount'
|
||||||
|
$ContainerName = 'myContainer'
|
||||||
|
$StorageEndpoint = 'core.windows.net'
|
||||||
|
$BundleManifestBlob = 'BundleManifest.json'
|
||||||
|
Install-BundleSoftware.ps1 -UserAssignedIdentityObjectId $UserAssignedIdentityObjectId
|
||||||
|
-StorageAccountName $StorageAccountName -ContainerName $ContainerName -StorageEndpoint
|
||||||
|
$StorageEndpoint -BundleManifestBlob $BundleManifestBlob
|
||||||
|
|
||||||
|
#>
|
||||||
|
|
||||||
|
param(
|
||||||
|
[string]$UserAssignedIdentityObjectId,
|
||||||
|
[string]$StorageAccountName,
|
||||||
|
[string]$ContainerName,
|
||||||
|
[string]$StorageEndpoint,
|
||||||
|
[string]$BundleManifestBlob
|
||||||
|
)
|
||||||
|
$ErrorActionPreference = 'Stop'
|
||||||
|
$WarningPreference = 'SilentlyContinue'
|
||||||
|
$StorageAccountUrl = "https://" + $StorageAccountName + ".blob." + $StorageEndpoint + "/"
|
||||||
|
$TokenUri = "http://169.254.169.254/metadata/identity/oauth2/token?api-version=2018-02-01&resource=$StorageAccountUrl&object_id=$UserAssignedIdentityObjectId"
|
||||||
|
$AccessToken = ((Invoke-WebRequest -Headers @{Metadata=$true} -Uri $TokenUri -UseBasicParsing).Content | ConvertFrom-Json).access_token
|
||||||
|
|
||||||
|
$BundleManifest = "$env:windir\temp\bundlemanifest.json"
|
||||||
|
Invoke-WebRequest -Headers @{"x-ms-version"="2017-11-09"; Authorization ="Bearer $AccessToken"} -Uri "$StorageAccountUrl$ContainerName$BundleManifestBlob" -OutFile $BundleManifest
|
||||||
|
$Bundle = Get-Content -Raw -Path $BundleManifest | ConvertFrom-Json
|
||||||
|
Start-Sleep -Seconds 5
|
||||||
|
|
||||||
|
foreach ($item in $Bundle) {
|
||||||
|
|
||||||
|
If($true -eq $item.Enabled) {
|
||||||
|
$Installer = $item.name
|
||||||
|
$BlobName = $item.blobName
|
||||||
|
$Arguments = $item.arguments
|
||||||
|
Write-Host "Downloading $Installer from $BlobName"
|
||||||
|
$BlobFileName = $BlobName.Split("/")[-1]
|
||||||
|
New-Item -Path $env:windir\temp -Name $Installer -ItemType "directory" -Force
|
||||||
|
$InstallerDirectory = "$env:windir\temp\$Installer"
|
||||||
|
Write-Host "Setting file copy to install directory: $InstallerDirectory"
|
||||||
|
Set-Location -Path $InstallerDirectory
|
||||||
|
Write-Host "Invoking WebClient download for file : $BlobFileName"
|
||||||
|
#Invoking WebClient to download blobs because it is more efficient than Invoke-WebRequest for large files.
|
||||||
|
$WebClient = New-Object System.Net.WebClient
|
||||||
|
$WebClient.Headers.Add('x-ms-version', '2017-11-09')
|
||||||
|
$webClient.Headers.Add("Authorization", "Bearer $AccessToken")
|
||||||
|
$webClient.DownloadFile("$StorageAccountUrl$ContainerName/$BlobName", "$InstallerDirectory\$BlobName")
|
||||||
|
Start-Sleep -Seconds 30
|
||||||
|
$Path = (Get-ChildItem -Path "$InstallerDirectory\$BlobName" -Recurse | Where-Object {$_.Name -eq "$BlobName"}).FullName
|
||||||
|
if($BlobName -like ("*.exe"))
|
||||||
|
{
|
||||||
|
Start-Process -FilePath $InstallerDirectory\$BlobName -ArgumentList $Arguments -NoNewWindow -Wait -PassThru
|
||||||
|
$wmistatus = Get-WmiObject -Class Win32_Product | Where-Object Name -like "*$($Installer)*"
|
||||||
|
if($wmistatus)
|
||||||
|
{
|
||||||
|
Write-Host $wmistatus.Name "is installed"
|
||||||
|
}
|
||||||
|
$regstatus = Get-ItemProperty 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*' | Where-Object { $_.DisplayName -like "*$($Installer)*" }
|
||||||
|
if($regstatus)
|
||||||
|
{
|
||||||
|
Write-Host $regstatus.DisplayName "is installed"
|
||||||
|
}
|
||||||
|
$regstatusWow6432 = Get-ItemProperty 'HKLM:\Software\WOW6432Node\*' | Where-Object { $_.PSChildName -like "*$($Installer)*" }
|
||||||
|
if($regstatusWow6432)
|
||||||
|
{
|
||||||
|
Write-Host $regstatusWow6432.PSChildName "is installed"
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Write-host $Installer "did not install properly, please check arguments"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if($BlobName -like ("*.msi"))
|
||||||
|
{
|
||||||
|
Write-Host "Invoking msiexec.exe for install path : $Path"
|
||||||
|
Start-Process -FilePath msiexec.exe -ArgumentList "/i $Path $Arguments" -Wait
|
||||||
|
$status = Get-WmiObject -Class Win32_Product | Where-Object Name -like "*$($installer)*"
|
||||||
|
if($status)
|
||||||
|
{
|
||||||
|
Write-Host $status.Name "is installed"
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Write-host $Installer "did not install properly, please check arguments"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if($BlobName -like ("*.bat"))
|
||||||
|
{
|
||||||
|
Start-Process -FilePath cmd.exe -ArgumentList $InstallerDirectory\$Arguments -Wait
|
||||||
|
}
|
||||||
|
if($BlobName -like ("*.ps1") -and $BlobName -notlike ("Install-BundleSoftware.ps1"))
|
||||||
|
{
|
||||||
|
Start-Process -FilePath PowerShell.exe -ArgumentList "-File $Path $Arguments" -Wait
|
||||||
|
}
|
||||||
|
if($BlobName -like ("*.zip"))
|
||||||
|
{
|
||||||
|
Expand-Archive -Path $InstallerDirectory\$BlobName -DestinationPath $InstallerDirectory -Force
|
||||||
|
Remove-Item -Path .\$BlobName -Force -Recurse
|
||||||
|
}
|
||||||
|
Write-Host "Removing $Installer Files"
|
||||||
|
Start-Sleep -Seconds 5
|
||||||
|
Remove-item $InstallerDirectory -Force -Recurse -Confirm:$false -ErrorAction SilentlyContinue
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"name": "Git",
|
||||||
|
"blobName": "Git-2.45.2-64-bit.exe",
|
||||||
|
"arguments": "/NORESTART /VERYSILENT /SUPPRESSMSGBOXES /FORCECLOSEAPPLICATIONS",
|
||||||
|
"enabled": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "VSCode",
|
||||||
|
"blobName": "VSCodeSetup-x64-1.91.1.exe",
|
||||||
|
"arguments": "/NORESTART /VERYSILENT /SUPPRESSMSGBOXES /MERGETASKS=!runcode",
|
||||||
|
"enabled": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "ScreenCaptureProtection",
|
||||||
|
"blobName": "Set-ScreenCaptureProtection.ps1",
|
||||||
|
"arguments": "",
|
||||||
|
"enabled": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "AzureStorageExplorer",
|
||||||
|
"blobName": "StorageExplorer-windows-x64.exe",
|
||||||
|
"arguments": "/NORESTART /VERYSILENT /SUPPRESSMSGBOXES /FORCECLOSEAPPLICATIONS /ALLUSERS",
|
||||||
|
"enabled": false
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "AzureCLI",
|
||||||
|
"blobName": "azure-cli-2.62.0-x64.msi",
|
||||||
|
"arguments": "/quiet /norestart",
|
||||||
|
"enabled": false
|
||||||
|
}
|
||||||
|
]
|
|
@ -12,8 +12,15 @@ param computeGalleryImageResourceId string = ''
|
||||||
@description('The name of the container in the storage account where the installer files are located.')
|
@description('The name of the container in the storage account where the installer files are located.')
|
||||||
param containerName string
|
param containerName string
|
||||||
|
|
||||||
@description('The array of customizations to apply to the image.')
|
@description('The array of customizations to apply to the image. Limit of 25 runCommands per virtual machine applies. Depending on other features used, the limit may be lower.')
|
||||||
param customizations array = []
|
param customizations array = [
|
||||||
|
{
|
||||||
|
name: 'InstallBundle'
|
||||||
|
blobName: 'Install-BundleSoftware.ps1'
|
||||||
|
arguments: '-BundleManifestBlob bundlemanifest.json'
|
||||||
|
enabled: false
|
||||||
|
}
|
||||||
|
]
|
||||||
|
|
||||||
@description('Choose whether to deploy a diagnostic setting for the Activity Log.')
|
@description('Choose whether to deploy a diagnostic setting for the Activity Log.')
|
||||||
param deployActivityLogDiagnosticSetting bool = false
|
param deployActivityLogDiagnosticSetting bool = false
|
||||||
|
@ -79,6 +86,9 @@ param imageDefinitionNamePrefix string
|
||||||
@description('The major version for the name of the image version resource.')
|
@description('The major version for the name of the image version resource.')
|
||||||
param imageMajorVersion int
|
param imageMajorVersion int
|
||||||
|
|
||||||
|
@description('The minor version for the name of the image version resource.')
|
||||||
|
param imageMinorVersion int
|
||||||
|
|
||||||
@description('The patch version for the name of the image version resource.')
|
@description('The patch version for the name of the image version resource.')
|
||||||
param imagePatchVersion int
|
param imagePatchVersion int
|
||||||
|
|
||||||
|
@ -285,7 +295,7 @@ module baseline 'modules/baseline.bicep' = {
|
||||||
exemptPolicyAssignmentIds: exemptPolicyAssignmentIds
|
exemptPolicyAssignmentIds: exemptPolicyAssignmentIds
|
||||||
location: location
|
location: location
|
||||||
mlzTags: tier3.outputs.mlzTags
|
mlzTags: tier3.outputs.mlzTags
|
||||||
resourceGroupName: tier3.outputs.namingConvention.resourceGroup
|
resourceGroupName: tier3.outputs.resourceGroupName
|
||||||
storageAccountResourceId: storageAccountResourceId
|
storageAccountResourceId: storageAccountResourceId
|
||||||
subscriptionId: subscriptionId
|
subscriptionId: subscriptionId
|
||||||
tags: tags
|
tags: tags
|
||||||
|
@ -315,6 +325,7 @@ module buildAutomation 'modules/buildAutomation.bicep' = if (enableBuildAutomati
|
||||||
hybridUseBenefit: hybridUseBenefit
|
hybridUseBenefit: hybridUseBenefit
|
||||||
imageDefinitionName: imageDefinitionName
|
imageDefinitionName: imageDefinitionName
|
||||||
imageMajorVersion: imageMajorVersion
|
imageMajorVersion: imageMajorVersion
|
||||||
|
imageMinorVersion: imageMinorVersion
|
||||||
imagePatchVersion: imagePatchVersion
|
imagePatchVersion: imagePatchVersion
|
||||||
imageVirtualMachineName: replace(tier3.outputs.namingConvention.virtualMachine, tier3.outputs.tokens.service, 'b')
|
imageVirtualMachineName: replace(tier3.outputs.namingConvention.virtualMachine, tier3.outputs.tokens.service, 'b')
|
||||||
installAccess: installAccess
|
installAccess: installAccess
|
||||||
|
@ -332,7 +343,7 @@ module buildAutomation 'modules/buildAutomation.bicep' = if (enableBuildAutomati
|
||||||
installVirtualDesktopOptimizationTool: installVirtualDesktopOptimizationTool
|
installVirtualDesktopOptimizationTool: installVirtualDesktopOptimizationTool
|
||||||
installVisio: installVisio
|
installVisio: installVisio
|
||||||
installWord: installWord
|
installWord: installWord
|
||||||
keyVaultName: tier3.outputs.namingConvention.keyVault
|
keyVaultName: tier3.outputs.keyVaultName
|
||||||
keyVaultPrivateDnsZoneResourceId: keyVaultPrivateDnsZoneResourceId
|
keyVaultPrivateDnsZoneResourceId: keyVaultPrivateDnsZoneResourceId
|
||||||
localAdministratorPassword: localAdministratorPassword
|
localAdministratorPassword: localAdministratorPassword
|
||||||
localAdministratorUsername: localAdministratorUsername
|
localAdministratorUsername: localAdministratorUsername
|
||||||
|
@ -347,7 +358,7 @@ module buildAutomation 'modules/buildAutomation.bicep' = if (enableBuildAutomati
|
||||||
officeInstaller: officeInstaller
|
officeInstaller: officeInstaller
|
||||||
oUPath: oUPath
|
oUPath: oUPath
|
||||||
replicaCount: replicaCount
|
replicaCount: replicaCount
|
||||||
resourceGroupName: tier3.outputs.namingConvention.resourceGroup
|
resourceGroupName: tier3.outputs.resourceGroupName
|
||||||
sourceImageType: sourceImageType
|
sourceImageType: sourceImageType
|
||||||
storageAccountResourceId: storageAccountResourceId
|
storageAccountResourceId: storageAccountResourceId
|
||||||
subnetResourceId: tier3.outputs.subnetResourceId
|
subnetResourceId: tier3.outputs.subnetResourceId
|
||||||
|
@ -381,6 +392,7 @@ module imageBuild 'modules/imageBuild.bicep' = {
|
||||||
hybridUseBenefit: hybridUseBenefit
|
hybridUseBenefit: hybridUseBenefit
|
||||||
imageDefinitionName: imageDefinitionName
|
imageDefinitionName: imageDefinitionName
|
||||||
imageMajorVersion: imageMajorVersion
|
imageMajorVersion: imageMajorVersion
|
||||||
|
imageMinorVersion: imageMinorVersion
|
||||||
imagePatchVersion: imagePatchVersion
|
imagePatchVersion: imagePatchVersion
|
||||||
imageVirtualMachineName: replace(tier3.outputs.namingConvention.virtualMachine, tier3.outputs.tokens.service, 'b')
|
imageVirtualMachineName: replace(tier3.outputs.namingConvention.virtualMachine, tier3.outputs.tokens.service, 'b')
|
||||||
installAccess: installAccess
|
installAccess: installAccess
|
||||||
|
@ -410,7 +422,7 @@ module imageBuild 'modules/imageBuild.bicep' = {
|
||||||
msrdcwebrtcsvcInstaller: msrdcwebrtcsvcInstaller
|
msrdcwebrtcsvcInstaller: msrdcwebrtcsvcInstaller
|
||||||
officeInstaller: officeInstaller
|
officeInstaller: officeInstaller
|
||||||
replicaCount: replicaCount
|
replicaCount: replicaCount
|
||||||
resourceGroupName: tier3.outputs.namingConvention.resourceGroup
|
resourceGroupName: tier3.outputs.resourceGroupName
|
||||||
sourceImageType: sourceImageType
|
sourceImageType: sourceImageType
|
||||||
storageAccountResourceId: storageAccountResourceId
|
storageAccountResourceId: storageAccountResourceId
|
||||||
subnetResourceId: tier3.outputs.subnetResourceId
|
subnetResourceId: tier3.outputs.subnetResourceId
|
||||||
|
|
|
@ -292,10 +292,12 @@ module defenderForCloud '../../modules/defender-for-cloud.bicep' =
|
||||||
|
|
||||||
output diskEncryptionSetResourceId string = customerManagedKeys.outputs.diskEncryptionSetResourceId
|
output diskEncryptionSetResourceId string = customerManagedKeys.outputs.diskEncryptionSetResourceId
|
||||||
output keyVaultUri string = customerManagedKeys.outputs.keyVaultUri
|
output keyVaultUri string = customerManagedKeys.outputs.keyVaultUri
|
||||||
|
output keyVaultName string = customerManagedKeys.outputs.keyVaultName
|
||||||
output locatonProperties object = logic.outputs.locationProperties
|
output locatonProperties object = logic.outputs.locationProperties
|
||||||
output mlzTags object = logic.outputs.mlzTags
|
output mlzTags object = logic.outputs.mlzTags
|
||||||
output namingConvention object = logic.outputs.tiers[0].namingConvention
|
output namingConvention object = logic.outputs.tiers[0].namingConvention
|
||||||
output privateDnsZones array = logic.outputs.privateDnsZones
|
output privateDnsZones array = logic.outputs.privateDnsZones
|
||||||
|
output resourceGroupName string = rg.outputs.name
|
||||||
output resourcePrefix string = azureFirewall.tags.resourcePrefix
|
output resourcePrefix string = azureFirewall.tags.resourcePrefix
|
||||||
output storageEncryptionKeyName string = customerManagedKeys.outputs.storageKeyName
|
output storageEncryptionKeyName string = customerManagedKeys.outputs.storageKeyName
|
||||||
output subnetResourceId string = networking.outputs.subnetResourceId
|
output subnetResourceId string = networking.outputs.subnetResourceId
|
||||||
|
|
Загрузка…
Ссылка в новой задаче