Export/Public/Start-CustomVMUpdate.ps1
# Will be called in VM function Start-CustomVMUpdate { [CmdletBinding()] <# .SYNOPSIS ... Parameters for Commands Command | Parameter 1 | Parameter 2 | JoinDomain | none | none | CreateInstances | Typefilter (e.g. "TEST") [x] | "RestartService" [ ] | UpdateInstanceConfiguration | Typefilter (e.g. "TEST") [x] | "RestartService" [ ] | UpdateLicense | URI to Licensefile [x] | "RestartService" [ ] | ... .DESCRIPTION ... #> param( [Parameter(Mandatory = $true)] [string] $ObjectName, [Parameter(Mandatory = $false)] [switch] $IsScaleSet, [Parameter(Mandatory = $true)] [string] $ResourceGroupName, [Parameter(Mandatory = $true)] [string] $StorageAccountName, [Parameter(Mandatory = $true)] [string] $KeyVaultName, [Parameter(Mandatory = $true)] [string] $StorageTableNameInfrastructureData, [Parameter(Mandatory = $false)] [string] $NewInstanceMarkerFilename ) process { Write-Verbose "Starting auto update..." if ($NewInstanceMarkerFilename) { Write-Verbose "Indicator for 'New Instance' is set." } # Uses managed identity to connect to Azure Account Connect-FromMachineToAzAccount # The current instance might still be in creation mode and might also automatically restart during this state # This will wait until the instance is marked as "ProvisioningState"="Succeeded" Wait-ForInstanceAvailability -ResourceGroupName $ResourceGroupName -ScaleSetName $ObjectName -Verbose:$Verbose # Disable Internet Explorer Enhanced Security Configuration (for Admins only) - because it's annoying Disable-InternetExplorerESC Write-Verbose "Loading pending commands..." $storageAccount = Get-AzStorageAccount -ResourceGroupName $ResourceGroupName -Name $StorageAccountName $storageAccountCtx = $storageAccount.Context $infrastructureData = Get-InfrastructureDataFromStorage -StorageAccountContext $storageAccountCtx -TableNameInfrastructureData $StorageTableNameInfrastructureData $TableNameSetup = $infrastructureData.SetupTable $TableNameEnvironments = $infrastructureData.EnvironmentsTable $TableNameEnvironmentDefaults = $infrastructureData.EnvironmentDefaultsTable $TableNameLog = $infrastructureData.LogTable $TableNameUsers = $infrastructureData.UsersTable $rows = Get-CommandsFromStorageTable -StorageAccountContext $storageAccountCtx -TableName $TableNameSetup -ObjectName $ObjectName foreach ($row in $rows) { if ($row.Command -ne 'SetupNotDone') { if (($NewInstanceMarkerFilename) -and (Test-Path $NewInstanceMarkerFilename)) { # It's possible that we have at one point 2 instances, then remove one and later add it again # The newly added instance might have the same computer name as a previous one and "previous" commands wouldn't be executed again # So this function will mark the previous ones as "Obsolete" Set-StorageCommandsObsolete -StorageAccountContext $storageAccountCtx -LogTableName $TableNameLog -LogObjectName $ObjectName -LogComputerName $env:computername # Delete File after that, so that we know, that everything is setup as expected Remove-Item $NewInstanceMarkerFilename -Force | Out-Null } } Write-Verbose "Checking if Command $($row.Command) was already executed" if (Get-StorageCommandExecutionLog -StorageAccountContext $storageAccountCtx -LogTableName $TableNameLog -CommandRow $row -ExecutedByName $env:computername) { Write-Verbose "Command $($row.Command) was already executed. Skipping to next one." continue } $infrastructureData = Get-InfrastructureDataFromStorage -StorageAccountContext $storageAccountCtx -TableNameInfrastructureData $StorageTableNameInfrastructureData -TypeFilter $row.Parameter1 Write-Verbose "Handling Command: $($row.Command)" switch ($row.Command) { 'SetupNotDone' { Write-Verbose "Setup is not done yet. Exiting here." if ($row.Parameter1 -eq 'ClearLog') { # Removing previous (unnecessary) log-files $logPath = "C:\Install\Log" if (Test-Path -Path $logPath) { Get-ChildItem $logPath\* -Include *.log | Select-Object -SkipLast 1 | Remove-Item -Force } } return } 'CreateInstances' { $params = @{ StorageAccountContext = $storageAccountCtx KeyVaultName = $KeyVaultName StorageTableNameEnvironments = $TableNameEnvironments StorageTableNameEnvironmentDefaults = $TableNameEnvironmentDefaults TypeFilter = $row.Parameter1 } Invoke-CreateInstances @params -Verbose:$Verbose } 'UpdateInstanceConfiguration' { $params = @{ StorageAccountContext = $storageAccountCtx KeyVaultName = $KeyVaultName StorageTableNameEnvironments = $TableNameEnvironments StorageTableNameEnvironmentDefaults = $TableNameEnvironmentDefaults TypeFilter = $row.Parameter1 Parameter2 = $row.Parameter2 RestartService = $row.RestartNecessary } Invoke-UpdateInstances @params -Verbose:$Verbose } 'UpdateLicense' { $params = @{ StorageAccountContext = $storageAccountCtx KeyVaultName = $KeyVaultName StorageTableNameEnvironments = $TableNameEnvironments StorageTableNameEnvironmentDefaults = $TableNameEnvironmentDefaults TypeFilter = $row.Parameter1 Parameter2 = $row.Parameter2 RestartService = $row.RestartNecessary } Invoke-UpdateLicenses @params -Verbose:$Verbose } 'CreateWebInstances' { $params = @{ StorageAccountContext = $storageAccountCtx KeyVaultName = $KeyVaultName StorageTableNameEnvironments = $TableNameEnvironments StorageTableNameEnvironmentDefaults = $TableNameEnvironmentDefaults TypeFilter = $row.Parameter1 Parameter2 = $row.Parameter2 InfrastructureData = $infrastructureData } Invoke-CreateWebInstances @params -Verbose:$Verbose } 'UpdateWebInstances' { $params = @{ StorageAccountContext = $storageAccountCtx KeyVaultName = $KeyVaultName StorageTableNameEnvironments = $TableNameEnvironments StorageTableNameEnvironmentDefaults = $TableNameEnvironmentDefaults TypeFilter = $row.Parameter1 Parameter2 = $row.Parameter2 InfrastructureData = $infrastructureData } Invoke-UpdateWebInstances @params -Verbose:$Verbose } 'CreateSPN' { $params = @{ StorageAccountContext = $storageAccountCtx KeyVaultName = $KeyVaultName TypeFilter = $row.Parameter1 Parameter2 = $row.Parameter2 InfrastructureData = $infrastructureData } Invoke-SetSpnForServices @params -Verbose:$Verbose } 'SetLoadbalancerDNSRecord' { $params = @{ KeyVaultName = $KeyVaultName InfrastructureData = $infrastructureData } Invoke-SetLoadBalancerDnsRecord @params -Verbose:$Verbose } 'SetupDelegation' { $params = @{ StorageAccountContext = $storageAccountCtx StorageTableNameEnvironments = $TableNameEnvironments TypeFilter = $row.Parameter1 KeyVaultName = $KeyVaultName InfrastructureData = $infrastructureData } Invoke-SetupDelegation @params -Verbose:$Verbose } 'RestartServices' { $params = @{ StorageAccountContext = $storageAccountCtx KeyVaultName = $KeyVaultName StorageTableNameEnvironments = $TableNameEnvironments TypeFilter = $row.Parameter1 } Invoke-RestartServices @params -Verbose:$Verbose } 'RestartIIS' { Write-Verbose "Restarting IIS service (using 'iisreset')" Invoke-Command -Scriptblock { iisreset } } 'AddUsers' { $params = @{ StorageAccountContext = $storageAccountCtx KeyVaultName = $KeyVaultName StorageTableNameEnvironments = $TableNameEnvironments StorageTableNameEnvironmentDefaults = $TableNameEnvironmentDefaults StorageTableNameUsers = $TableNameUsers TypeFilter = $row.Parameter1 } Invoke-AddUsers @params -Verbose:$Verbose } 'SetupCertificate' { $params = @{ StorageAccountContext = $storageAccountCtx KeyVaultName = $KeyVaultName StorageTableNameEnvironments = $TableNameEnvironments StorageTableNameEnvironmentDefaults = $TableNameEnvironmentDefaults TypeFilter = $row.Parameter1 CertificateType = "" RestartService = $row.RestartNecessary } switch (Get-MachineInstanceType -InfrastructureData $infrastructureData) { 'Application' { $params.CertificateType = "ServiceInstance" Invoke-SetupCertificateAppServer @params -Verbose:$Verbose } 'Web' { $params.CertificateType = "Webclient" Invoke-SetupCertificateWebServer @params -Verbose:$Verbose } } } default { Write-Verbose "Not implemented yet." } } Set-StorageCommandExecuted -CommandRow $row -ExecutedByName $env:computername -StorageAccountContext $storageAccountCtx -LogTableName $TableNameLog } } } |