Private/Submit-ScriptToVmAndExecute.ps1
function Global:Submit-ScriptToVmAndExecute { [CmdletBinding()] <# .SYNOPSIS ... .DESCRIPTION ... Do not pass any secure-objects in $RunParameter (like SecureString for Passwords); these will cause to run indefinitely #> param( [Parameter(Mandatory = $true)] [string] $ResourceGroupName, [Parameter(Mandatory = $true)] [string] $ResourceLocation, [Parameter(Mandatory = $true)] [string] $VMName, [Parameter(Mandatory = $true)] [ValidateSet('InstallD365Module', 'InitVM', 'DownloadBC', 'InstallBC', 'GeneralizeVM', 'WriteProperties', 'CreateUpdateScheduledTask', 'InvokeAutoUpdate', 'UpdateNetworkSettings', 'EnableRemoting', 'WaitForNetwork', 'WriteDiagnoseInformation', 'ConfigureSqlServer', 'ConfigureSqlServerDomain', 'RestoreDemoDatabase','InstallChoco')] [string] $ScriptBlockName, [Parameter(Mandatory = $false)] $RunParameter, [Parameter(Mandatory = $false)] [string] $MsgBeforeExecuting, [Parameter(Mandatory = $false)] [switch] $ScaleSetExecution = $false ) process { # Load Scripts from separate file . $PSScriptRoot\Scriptblocks.ps1 # Check tags on resource (not for Scale Sets / only for checks during Image creation) $tagName = "Command $ScriptBlockName" if (-not($ScaleSetExecution)) { $vm = Get-AzVM -ResourceGroupName $ResourceGroupName -Name $VMName if ($vm.Tags.ContainsKey($tagName)) { Write-CustomHost -Message "Command $ScriptBlockName was already executed." return } } if ($MsgBeforeExecuting) { Write-CustomHost -Message $MsgBeforeExecuting } $fullscriptpath = New-TemporaryFile | Rename-Item -NewName { $_ -replace 'tmp$', 'ps1' } -PassThru | Select-Object -ExpandProperty FullName $content = "" switch ($ScriptBlockName) { 'InstallD365Module' { $content = $installD365Module } 'InitVM' { $content = $initializeVm } 'DownloadBC' { $content = $downloadBCDVD } 'InstallBC' { $content = $installBC } 'GeneralizeVM' { $content = $generalizeVM } 'WriteProperties' { $content = $writeProperties } 'CreateUpdateScheduledTask' { $content = $createUpdateScheduledTask } 'InvokeAutoUpdate' { $content = $invokeAutoUpdate } 'UpdateNetworkSettings' { $content = $setNetConnectionProfile } 'WaitForNetwork' { $content = $waitForNetwork } 'EnableRemoting' { $content = $enableRemoting } 'WriteDiagnoseInformation' { $content = $saveDiagInformation } 'ConfigureSqlServer' { $content = $configureSqlServer } 'ConfigureSqlServerDomain' { $content = $configureSqlServerDomain } 'RestoreDemoDatabase' { $content = $restoreSqlDemoDatabase } 'InstallChoco' { $content = $installChoco } } Set-Content -Path $fullscriptpath -Value $content Write-CustomHost -Message "Updating tags on resource..." # Tag VM / VMSS $resource = Get-AzResource -ResourceGroupName $ResourceGroupName -Name $VMName $existingTags = $resource.Tags if ($existingTags.Count -ne 0) { if (-not($existingTags.ContainsKey($tagName))) { $existingTags.Add($tagName, "Started") Set-AzResource -ResourceId $resource.Id -Tag $existingTags -Force | Out-Null } else { $existingTags.$tagName = "Started" Set-AzResource -ResourceId $resource.Id -Tag $existingTags -Force | Out-Null } } else { Set-AzResource -ResourceId $resource.Id -Tag @{$tagName = "Started" } -Force | Out-Null } Write-CustomHost -Message "Running command '$ScriptBlockName' on VM $VMName..." if (-not($ScaleSetExecution)) { Invoke-AzVMRunCommand -ResourceGroupName $ResourceGroupName -VMName $VMName -CommandId 'RunPowerShellScript' -ScriptPath $fullscriptpath -Parameter $RunParameter | Out-Null } else { foreach ($instance in Get-AzVmssVM -ResourceGroupName $ResourceGroupName -VMScaleSetName $VMName) { $instanceId = $instance.InstanceId Write-CustomHost -Message "on Instance $instanceId..." Invoke-AzVmssVMRunCommand -ResourceGroupName $ResourceGroupName -VMScaleSetName $VMName -InstanceId $instanceId -CommandId 'RunPowerShellScript' -ScriptPath $fullscriptpath -Parameter $RunParameter | Out-Null } } Write-CustomHost -Message "Command completed." Write-CustomHost -Message "Updating tags on resource..." $resource = Get-AzResource -ResourceGroupName $ResourceGroupName -Name $VMName $existingTags = $resource.Tags $existingTags.$tagName = "Executed" Set-AzResource -ResourceId $resource.Id -Tag $existingTags -Force | Out-Null Remove-Item $fullscriptpath -Force } } |