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 $StartDate = (Get-Date) while (-not($done)) { try { $noOfTries if (Test-NetConnection) { $done = $true $success = $true } else { Start-Sleep -Seconds 2 } } catch { # Do nothing } $noOfTries++ if ($noOfTries -ge 30) { # 50 tries max $done = $true } $duration = New-TimeSpan -Start $StartDate -End (Get-Date) if ($duration.Seconds -ge 300) { # Wait 5 Minutes top $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 } $configureSqlServer = { param( [Parameter(Mandatory = $true)] [string] $SqlUser, [Parameter(Mandatory = $true)] [string] $SqlPass ) 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\SqlConfig.$(get-date -format yyyyMMddhhmmss).log" $scriptBlock = { param( [Parameter(Mandatory = $true)] [string] $SqlUser, [Parameter(Mandatory = $true)] [string] $SqlPass ) $assemblylist = "Microsoft.SqlServer.Management.Common", "Microsoft.SqlServer.Smo", "Microsoft.SqlServer.Dmf ", "Microsoft.SqlServer.Instapi ", "Microsoft.SqlServer.SqlWmiManagement ", "Microsoft.SqlServer.ConnectionInfo ", "Microsoft.SqlServer.SmoExtended ", "Microsoft.SqlServer.SqlTDiagM ", "Microsoft.SqlServer.SString ", "Microsoft.SqlServer.Management.RegisteredServers ", "Microsoft.SqlServer.Management.Sdk.Sfc ", "Microsoft.SqlServer.SqlEnum ", "Microsoft.SqlServer.RegSvrEnum ", "Microsoft.SqlServer.WmiEnum ", "Microsoft.SqlServer.ServiceBrokerEnum ", "Microsoft.SqlServer.ConnectionInfoExtended ", "Microsoft.SqlServer.Management.Collector ", "Microsoft.SqlServer.Management.CollectorEnum", "Microsoft.SqlServer.Management.Dac", "Microsoft.SqlServer.Management.DacEnum", "Microsoft.SqlServer.Management.Utility" foreach ($asm in $assemblylist) { $asm = [Reflection.Assembly]::LoadWithPartialName($asm) } $s = new-object ('Microsoft.SqlServer.Management.Smo.Server') $env:computername $s.Name $s.LoginMode $s.Settings.LoginMode = [Microsoft.SqlServer.Management.SMO.ServerLoginMode]::Mixed $s.Alter() Get-Service -Name MSSQLSERVER | Restart-Service -Force $SQLLogin = [Microsoft.SqlServer.Management.Smo.Login]::New($s, $SqlUser) $SQLLogin.LoginType = [Microsoft.SqlServer.Management.Smo.LoginType]::SqlLogin $SQLLogin.PasswordPolicyEnforced = $False $SQLLogin.Create((ConvertTo-SecureString $SqlPass -AsPlainText -Force)) $svrole = $s.Roles | where { $_.Name -eq 'sysadmin' }; $svrole.AddMember($SqlUser); } try { $VMCredentials = New-Object System.Management.Automation.PSCredential ("$($env:computername)\$SqlUser", (ConvertTo-SecureString $SqlPass -AsPlainText -Force)) #Enter-PSSession -ComputerName $env:computername -Credential $VMCredentials $session = New-PSSession -ComputerName $env:computername -Credential $VMCredentials #Invoke-Command -computername $env:computername -Credential $VMCredentials -ScriptBlock $scriptBlock -ArgumentList $SqlUser, $SqlPass #Invoke-Command -ScriptBlock $scriptBlock -ArgumentList $SqlUser, $SqlPass Invoke-Command -ScriptBlock $scriptBlock -ArgumentList $SqlUser, $SqlPass -Session $session #Exit-PSSession $session | Remove-PSSession } catch { # Do nothing } Stop-Transcript } $configureSqlServerDomain = { param( [Parameter(Mandatory = $true)] [string] $SqlUser, [Parameter(Mandatory = $true)] [string] $SqlPass, [Parameter(Mandatory = $true)] [string] $DomainName ) 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\SqlConfigDomain.$(get-date -format yyyyMMddhhmmss).log" $scriptBlock = { param( [Parameter(Mandatory = $true)] [string] $SqlUser, [Parameter(Mandatory = $true)] [string] $SqlPass, [Parameter(Mandatory = $true)] [string] $DomainName ) $assemblylist = "Microsoft.SqlServer.Management.Common", "Microsoft.SqlServer.Smo", "Microsoft.SqlServer.Dmf ", "Microsoft.SqlServer.Instapi ", "Microsoft.SqlServer.SqlWmiManagement ", "Microsoft.SqlServer.ConnectionInfo ", "Microsoft.SqlServer.SmoExtended ", "Microsoft.SqlServer.SqlTDiagM ", "Microsoft.SqlServer.SString ", "Microsoft.SqlServer.Management.RegisteredServers ", "Microsoft.SqlServer.Management.Sdk.Sfc ", "Microsoft.SqlServer.SqlEnum ", "Microsoft.SqlServer.RegSvrEnum ", "Microsoft.SqlServer.WmiEnum ", "Microsoft.SqlServer.ServiceBrokerEnum ", "Microsoft.SqlServer.ConnectionInfoExtended ", "Microsoft.SqlServer.Management.Collector ", "Microsoft.SqlServer.Management.CollectorEnum", "Microsoft.SqlServer.Management.Dac", "Microsoft.SqlServer.Management.DacEnum", "Microsoft.SqlServer.Management.Utility" foreach ($asm in $assemblylist) { $asm = [Reflection.Assembly]::LoadWithPartialName($asm) } $s = new-object ('Microsoft.SqlServer.Management.Smo.Server') $env:computername Get-Service -Name MSSQLSERVER | Restart-Service -Force $SQLLogin = [Microsoft.SqlServer.Management.Smo.Login]::New($s, "$DomainName\$SqlUser") $SQLLogin.LoginType = [Microsoft.SqlServer.Management.Smo.LoginType]::WindowsUser $SQLLogin.PasswordPolicyEnforced = $False $SQLLogin.Create((ConvertTo-SecureString $SqlPass -AsPlainText -Force)) $svrole = $s.Roles | where { $_.Name -eq 'sysadmin' }; $svrole.AddMember("$DomainName\$SqlUser"); } try { $VMCredentials = New-Object System.Management.Automation.PSCredential ("$($env:computername)\$SqlUser", (ConvertTo-SecureString $SqlPass -AsPlainText -Force)) #Enter-PSSession -ComputerName $env:computername -Credential $VMCredentials $session = New-PSSession -ComputerName $env:computername -Credential $VMCredentials #Invoke-Command -computername $env:computername -Credential $VMCredentials -ScriptBlock $scriptBlock -ArgumentList $SqlUser, $SqlPass #Invoke-Command -ScriptBlock $scriptBlock -ArgumentList $SqlUser, $SqlPass Invoke-Command -ScriptBlock $scriptBlock -ArgumentList $SqlUser, $SqlPass, $DomainName -Session $session #Exit-PSSession $session | Remove-PSSession } catch { # Do nothing } Stop-Transcript } |