Private/Scriptblocks.ps1

$installD365Module = {
    try {
        Stop-Transcript | out-null
    }
    catch {
        $error.clear()   
    }
    New-Item -ItemType Directory -Force -Path C:\Install\Log -ErrorAction SilentlyContinue | Out-Null
    Start-Transcript -Path "C:\Install\Log\InstallD365Module.$(get-date -format yyyyMMddhhmmss).log"
    if (Get-Module -Name SetupD365Environment -ListAvailable) {
        Write-Host "Updating module SetupD365Environment..."
        Update-Module -Name SetupD365Environment -Force
    }
    else {
        Write-Host "Installing module SetupD365Environment..."
        Install-Module -Name SetupD365Environment -Force
    }
    Stop-Transcript
}

$initializeVm = {
    $ErrorActionPreference = "SilentlyContinue"
    try {
        Stop-Transcript | out-null
    }
    catch {
        $error.clear()
    }
    New-Item -ItemType Directory -Force -Path C:\Install\Log -ErrorAction SilentlyContinue | Out-Null
    Start-Transcript -Path "C:\Install\Log\InitVM.$(get-date -format yyyyMMddhhmmss).log"
    Import-Module -Name SetupD365Environment
    if (Get-Module -Name Cloud.Ready.Software.NAV -ListAvailable) {
        Write-Host "Updating module Cloud.Ready.Software.NAV..."
        Update-Module -Name Cloud.Ready.Software.NAV -Force
    }
    else {
        Write-Host "Installing module Cloud.Ready.Software.NAV..."
        Install-Module -Name Cloud.Ready.Software.NAV -Force
    }
    Initialize-CustomAzVm
    Stop-Transcript
}

$downloadBCDVD = {
    Param(
        [Parameter(Mandatory = $false, Position = 3)]
        [string]
        $Version,
        [Parameter(Mandatory = $false, Position = 4)]
        [string]
        $CumulativeUpdate,
        [Parameter(Mandatory = $false, Position = 5)]
        [string]
        $Language
    )
    try {
        Stop-Transcript | out-null
    }
    catch {
        $error.clear()
    }
    Start-Transcript -Path "C:\Install\Log\DownloadBC.$(get-date -format yyyyMMddhhmmss).log"
    Import-Module SetupD365Environment
    Write-Host "Version: $Version CU: $CumulativeUpdate Lang: $Language..."
    Receive-BusinessCentralDVD -Version $Version -CumulativeUpdate $CumulativeUpdate -Language $Language
    Stop-Transcript
}

$installBC = {
    Param(
        [Parameter(Mandatory = $false, Position = 1)]
        [string]
        $DownloadDirectory,
        [Parameter(Mandatory = $false, Position = 2)]
        [string]
        $ConfigurationFile,
        [Parameter(Mandatory = $false, Position = 3)]
        [string]
        $LicenseFilename,
        [Parameter(Mandatory = $false, Position = 4)]
        [ValidateSet('13', '14', '15')]
        [string]
        $Version,
        [ValidateSet('App', 'Web')]
        [Parameter(Mandatory = $false, Position = 5)]
        [string]
        $InstallationType = "App"
    )
    try {
        Stop-Transcript | out-null
    }
    catch {
        $error.clear()
    }    
    Start-Transcript -Path "C:\Install\Log\InstallBC.$(get-date -format yyyyMMddhhmmss).log"
    # TODO: Remove later >>
    Update-Module -Name SetupD365Environment -Force
    # TODO <<
    Import-Module SetupD365Environment
    Write-Host "Installing Business Central"    
    $InstallArgs = @{        
    }
    if (-not([string]::IsNullOrEmpty($DownloadDirectory))) {
        $InstallArgs.Add('DownloadDirectory', $DownloadDirectory)
    }
    if (-not([string]::IsNullOrEmpty($ConfigurationFile))) {
        $InstallArgs.Add('ConfigurationFile', $ConfigurationFile)
    }
    if (-not([string]::IsNullOrEmpty($LicenseFilename))) {
        $InstallArgs.Add('LicenseFilename', $LicenseFilename)
    }
    if (-not([string]::IsNullOrEmpty($Version))) {
        $InstallArgs.Add('Version', $Version)
    }
    if (-not([string]::IsNullOrEmpty($InstallationType))) {
        $InstallArgs.Add('InstallationType', $InstallationType)
    }
    Install-BusinessCentral @InstallArgs
    
    # Set default Service to disabled
    Get-Service | Where-Object { $_.Name -like 'MicrosoftDynamicsNavServer*' } | Set-Service -StartupType Disabled
    Get-Service | Where-Object { $_.Name -like 'MicrosoftDynamicsNavServer*' } | Stop-Service
    Stop-Transcript
}

$generalizeVM = {
    try {
        Stop-Transcript | out-null
    }
    catch {
        $error.clear()
    }    
    Start-Transcript -Path "C:\Install\Log\GeneralizeVM.$(get-date -format yyyyMMddhhmmss).log"
    Write-Host "Generalizing VM. "
    Write-Host "About to call 'Sysprep.exe /generalize /oobe /shutdown /quiet'"
    Stop-Transcript
    $sysprep = 'C:\Windows\System32\Sysprep\Sysprep.exe'
    $arg = '/generalize /oobe /shutdown'
    Start-Process -FilePath $sysprep -ArgumentList $arg    
}

$writeProperties = {
    param(
        [Parameter(Mandatory = $false, Position = 1)]
        [string]
        $VMName,
        [Parameter(Mandatory = $false, Position = 2)]
        [string]
        $ScaleSetName,
        [Parameter(Mandatory = $true, Position = 3)]
        [string]
        $ResourceGroupName,
        [Parameter(Mandatory = $true, Position = 4)]
        [string]
        $StorageAccountName,
        [Parameter(Mandatory = $true, Position = 5)]
        [string]
        $KeyVaultName,
        [Parameter(Mandatory = $true, Position = 6)]
        [string]
        $StorageTableNameSetup,
        [Parameter(Mandatory = $true, Position = 7)]
        [string]
        $StorageTableNameEnvironments,
        [Parameter(Mandatory = $true, Position = 8)]
        [string]
        $StorageTableNameEnvironmentDefaults
    )
    $targetFolder = 'C:\Install\AutoUpdate'
    New-Item -ItemType Directory -Path $targetFolder -ErrorAction SilentlyContinue | Out-Null
    $fullscriptpath = Join-Path $targetFolder 'Properties.ps1'
    
    $content = "
    `$VMName = '$VMName'
    `$ScaleSetName = '$ScaleSetName'
    `$ResourceGroupName = '$ResourceGroupName'
    `$StorageAccountName = '$StorageAccountName'
    `$KeyVaultName = '$KeyVaultName'
    `$StorageTableNameSetup = '$StorageTableNameSetup'
    `$StorageTableNameEnvironments = '$StorageTableNameEnvironments'
    `$StorageTableNameEnvironmentDefaults = '$StorageTableNameEnvironmentDefaults'
    "
    
    Set-Content -Path $fullscriptpath -Value $content
}

$createUpdateScheduledTask = {
    $targetFolder = 'C:\Install\AutoUpdate'
    New-Item -ItemType Directory -Path $targetFolder -ErrorAction SilentlyContinue | Out-Null
    
    $fullscriptpath = Join-Path $targetFolder 'AutoUpdate.ps1'
    
    $scriptblock = {
        try {
            Stop-Transcript | out-null
        }
        catch {
            $error.clear()
        }
        Start-Transcript -Path "C:\Install\Log\AutoUpdate.$(get-date -format yyyyMMddhhmmss).log"        
        if (Get-Module -Name SetupD365Environment -ListAvailable) {
            Update-Module -Name SetupD365Environment -Force
        }
        else {
            Install-Module -Name SetupD365Environment -Force
        }
        Import-Module -Name SetupD365Environment
        Test-CustomNetworkAvailable
        if ((Set-CustomNetworkSettings) -eq $true) {
            Write-Host "Updated network settings. Restarting machine..."
            Restart-Computer -Force
            return
        }
        . ("C:\Install\AutoUpdate\Properties.ps1")
        $Instance = $false
        if (-not([string]::IsNullOrEmpty($VMName))) {
            $ObjectName = $VMName
        }
        else {
            $ObjectName = $ScaleSetName
            $Instance = $true
        }
        Start-CustomVMUpdate -ObjectName $ObjectName -IsScaleSet:$Instance -ResourceGroupName $ResourceGroupName -StorageAccountName $StorageAccountName -KeyVaultName $KeyVaultName -StorageTableNameSetup $StorageTableNameSetup -StorageTableNameEnvironments $StorageTableNameEnvironments -StorageTableNameEnvironmentDefaults $StorageTableNameEnvironmentDefaults
        Stop-Transcript
    }
    
    Set-Content -Path $fullscriptpath -Value $scriptblock
    
    $action = New-ScheduledTaskAction -Execute 'Powershell.exe' `
        -Argument "-NoProfile -WindowStyle Hidden -ExecutionPolicy Unrestricted -File `"$fullscriptpath`""
    $trigger = New-ScheduledTaskTrigger -AtStartup
    $taskPrinicpal = New-ScheduledTaskPrincipal -UserID "NT AUTHORITY\SYSTEM" -LogonType  ServiceAccount -RunLevel Highest
    Register-ScheduledTask -Action $action -Trigger $trigger -Principal $taskPrinicpal -TaskName "CustomAutoUpdate" -Description "Update Azure Machine" | Out-Null   
}

$invokeAutoUpdate = {    
    . ("C:\Install\AutoUpdate\AutoUpdate.ps1")
}

$setNetConnectionProfile = {    
    $restartNecessary = $false
    foreach ($netConProfile in Get-NetConnectionProfile) {
        if ($netConProfile.NetworkCategory -ne 'Private') {
            Set-NetConnectionProfile -Name $netConProfile.Name -NetworkCategory Private
            $restartNecessary = $true
        }        
    }
    foreach ($profile in Get-NetConnectionProfile | Where-Object { $_.InterfaceAlias -like 'Ethernet*' }) {
        Set-DnsClientServerAddress -InterfaceIndex $profile.InterfaceIndex -ServerAddresses ("10.0.0.4") # TODO: Change to DC IP
    }
    if ($restartNecessary) {
        Restart-Computer -Force
    }    
}

$enableRemoting = {    
    Enable-PSRemoting -Force
    Set-NetFirewallRule -Name "WINRM-HTTP-In-TCP-PUBLIC" -RemoteAddress Any
    Set-NetFirewallRule -Name "WINRM-HTTP-In-TCP-PUBLIC" -LocalAddress Any
}

$waitForNetwork = {
    $done = $false
    $success = $false
    $noOfTries = 0
    while (-not($done)) {
        try {
            $noOfTries
            if (Test-NetConnection) {
                $done = $true
                $success = $true
            }
            else {
                Start-Sleep -Seconds 2
            }
        }
        catch {
            # Do nothing
        }
        $noOfTries++
        if ($noOfTries -ge 180) {
            # 50 tries max
            $done = $true
        } 
    }
    if (-not($success)) {
        throw "Checked Test-NetConnection $noOfTries times, without success."
    }
}

$saveDiagInformation = {
    $filename = "C:\Install\Log\DiagnoseInformation.$(get-date -format yyyyMMddhhmmss).log"
    "Output from: Get-NetIPConfiguration -All" | Out-File -FilePath $filename -Append
    "========================================" | Out-File -FilePath $filename -Append
    Get-NetIPConfiguration -All | Out-File -FilePath $filename -Append
    "========================================" | Out-File -FilePath $filename -Append
    "Output from: Get-NetConnectionProfile" | Out-File -FilePath $filename -Append
    "========================================" | Out-File -FilePath $filename -Append
    Get-NetConnectionProfile | Out-File -FilePath $filename -Append
    "========================================" | Out-File -FilePath $filename -Append
    "Output from: Get-Service | Format-Table -AutoSize" | Out-File -FilePath $filename -Append
    "========================================" | Out-File -FilePath $filename -Append
    Get-Service | Format-Table -AutoSize | Out-File -FilePath $filename -Append
    "========================================" | Out-File -FilePath $filename -Append
}