diff --git a/Scripts/0_Shared.ps1 b/Scripts/0_Shared.ps1 index a7db48bf..3a4893db 100644 --- a/Scripts/0_Shared.ps1 +++ b/Scripts/0_Shared.ps1 @@ -155,7 +155,7 @@ function Get-PcSystemType { $aiPropertyCache = @{} -function New-TelemetryEvent { +function Initialize-TelemetryEvent { param( [Parameter(Mandatory = $true)] [string]$Event, @@ -303,12 +303,12 @@ function Send-TelemetryEvent { ) process { - $telemetryEvent = New-TelemetryEvent -Event $Event -Properties $Properties -Metrics $Metrics -NickName $NickName + $telemetryEvent = Initialize-TelemetryEvent -Event $Event -Properties $Properties -Metrics $Metrics -NickName $NickName Send-TelemetryObject -Data $telemetryEvent } } -function Send-TelemetryEvents { +function Send-TelemetryEvent { param( [Parameter(Mandatory = $true)] [array]$Events diff --git a/Scripts/1_Prereq.ps1 b/Scripts/1_Prereq.ps1 index e2df7c8a..d2276b69 100644 --- a/Scripts/1_Prereq.ps1 +++ b/Scripts/1_Prereq.ps1 @@ -4,11 +4,11 @@ If (-not $isAdmin) { Write-Host "-- Restarting as Administrator" -ForegroundColor Cyan ; Start-Sleep -Seconds 1 if($PSVersionTable.PSEdition -eq "Core") { - Start-Process pwsh.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs + Start-Process pwsh.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs } else { - Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs + Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs } - + exit } @@ -18,10 +18,10 @@ If (-not $isAdmin) { #region Functions . $PSScriptRoot\0_Shared.ps1 # [!build-include-inline] -function Get-WindowsBuildNumber { +function Get-WindowsBuildNumber { $os = Get-CimInstance -ClassName Win32_OperatingSystem - return [int]($os.BuildNumber) -} + return [int]($os.BuildNumber) +} #endregion #region Initialization @@ -128,7 +128,7 @@ function Get-WindowsBuildNumber { Invoke-WebRequest -UseBasicParsing -Uri "https://github.com/microsoft/MSLab/releases/download/$mslabVersion/$Filename.ps1" -OutFile $path } catch { WriteInfo "Download $filename failed with $($_.Exception.Message), trying master branch now" - + # if that fails, try master branch $FileContent = (Invoke-WebRequest -UseBasicParsing -Uri "https://raw.githubusercontent.com/microsoft/MSLab/master/Tools/$FileName.ps1").Content if ($FileContent) { @@ -166,7 +166,7 @@ function Get-WindowsBuildNumber { WriteInfoHighlighted "Testing diskspd presence" If ( Test-Path -Path "$PSScriptRoot\Temp\ToolsVHD\DiskSpd\diskspd.exe" ) { WriteSuccess "`t Diskspd is present, skipping download" - }else{ + }else{ WriteInfo "`t Diskspd not there - Downloading diskspd" try { <# aka.ms/diskspd changed. Commented @@ -197,13 +197,13 @@ function Get-WindowsBuildNumber { $modules=("xActiveDirectory","3.0.0.0"),("xDHCpServer","2.0.0.0"),("xDNSServer","1.15.0.0"),("NetworkingDSC","7.4.0.0"),("xPSDesiredStateConfiguration","8.10.0.0") foreach ($module in $modules){ - WriteInfoHighlighted "Testing if modules are present" + WriteInfoHighlighted "Testing if modules are present" $modulename=$module[0] $moduleversion=$module[1] if (!(Test-Path "$PSScriptRoot\Temp\DSC\$modulename\$Moduleversion")){ WriteInfo "`t Module $module not found... Downloading" - #Install NuGET package provider - if ((Get-PackageProvider -Name NuGet) -eq $null){ + #Install NuGET package provider + if ((Get-PackageProvider -Name NuGet) -eq $null){ Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Confirm:$false -Force } Find-DscResource -moduleName $modulename -RequiredVersion $moduleversion | Save-Module -Path "$PSScriptRoot\Temp\DSC" @@ -238,24 +238,24 @@ if($LabConfig.Linux -eq $true) { WriteInfo "`t Test Packer availability" # Packer - if (Get-Command "packer.exe" -ErrorAction SilentlyContinue) - { + if (Get-Command "packer.exe" -ErrorAction SilentlyContinue) + { WriteSuccess "`t Packer is in PATH." } else { WriteInfo "`t`t Downloading latest Packer binary" WriteInfo "`t`t Creating packer directory" - $linuxToolsDirPath = "$PSScriptRoot\LAB\bin" + $linuxToolsDirPath = "$PSScriptRoot\LAB\bin" New-Item $linuxToolsDirPath -ItemType Directory -Force | Out-Null - + if(-not (Test-Path (Join-Path $linuxToolsDirPath "packer.exe"))) { $packerReleaseInfo = Invoke-RestMethod -Uri "https://checkpoint-api.hashicorp.com/v1/check/packer" - $downloadUrl = "https://releases.hashicorp.com/packer/$($packerReleaseInfo.current_version)/packer_$($packerReleaseInfo.current_version)_windows_amd64.zip" - Start-BitsTransfer -Source $downloadUrl -Destination (Join-Path $linuxToolsDirPath "packer.zip") + $downloadUrl = "https://releases.hashicorp.com/packer/$($packerReleaseInfo.current_version)/packer_$($packerReleaseInfo.current_version)_windows_amd64.zip" + Start-BitsTransfer -Source $downloadUrl -Destination (Join-Path $linuxToolsDirPath "packer.zip") Expand-Archive -Path (Join-Path $linuxToolsDirPath "packer.zip") -DestinationPath $linuxToolsDirPath -Force - Remove-Item -Path (Join-Path $linuxToolsDirPath "packer.zip") + Remove-Item -Path (Join-Path $linuxToolsDirPath "packer.zip") } - + WriteInfo "`t`t Creating Packer firewall rule" $id = $PSScriptRoot -replace '[^a-zA-Z0-9]' $fwRule = Get-NetFirewallRule -Name "mslab-packer-$id" -ErrorAction SilentlyContinue @@ -268,7 +268,7 @@ if($LabConfig.Linux -eq $true) { WriteInfo "`t`t Downloading Packer templates" $packerTemplatesDirectory = "$PSScriptRoot\ParentDisks\PackerTemplates\" if (-not (Test-Path $packerTemplatesDirectory)) { - New-Item -Type Directory -Path $packerTemplatesDirectory + New-Item -Type Directory -Path $packerTemplatesDirectory } $templatesBase = "https://github.com/microsoft/mslab-templates/releases/latest/download/" @@ -309,11 +309,11 @@ if($LabConfig.Linux -eq $true) { if($comparison) { WriteError "`t SSH Keypair $($LabConfig.SshKeyPath) does not match." } - } - else + } + else { WriteInfo "`t`t Generating new SSH key pair" - $sshKeyDir = "$PSScriptRoot\LAB\.ssh" + $sshKeyDir = "$PSScriptRoot\LAB\.ssh" $key = "$sshKeyDir\lab_rsa" New-Item -ItemType Directory $sshKeyDir -ErrorAction SilentlyContinue | Out-Null ssh-keygen.exe -t rsa -b 4096 -C "$($LabConfig.DomainAdminName)" -f $key -q -N '""' @@ -326,11 +326,11 @@ if((Get-TelemetryLevel) -in $TelemetryEnabledLevels) { $metrics = @{ 'script.duration' = ((Get-Date) - $StartDateTime).TotalSeconds } - + Send-TelemetryEvent -Event "Prereq.End" -Metrics $metrics -NickName $LabConfig.TelemetryNickName | Out-Null } -# finishing +# finishing WriteInfo "Script finished at $(Get-date) and took $(((get-date) - $StartDateTime).TotalMinutes) Minutes" Stop-Transcript @@ -338,4 +338,4 @@ Stop-Transcript If (!$LabConfig.AutoClosePSWindows) { WriteSuccess "Press enter to continue..." Read-Host | Out-Null -} \ No newline at end of file +} diff --git a/Scripts/2_CreateParentDisks.ps1 b/Scripts/2_CreateParentDisks.ps1 index fe4c1d05..d37352f0 100644 --- a/Scripts/2_CreateParentDisks.ps1 +++ b/Scripts/2_CreateParentDisks.ps1 @@ -4,9 +4,9 @@ If (-not $isAdmin) { Write-Host "-- Restarting as Administrator" -ForegroundColor Cyan ; Start-Sleep -Seconds 1 if($PSVersionTable.PSEdition -eq "Core") { - Start-Process pwsh.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs + Start-Process pwsh.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs } else { - Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs + Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs } exit @@ -15,7 +15,7 @@ If (-not $isAdmin) { #region Functions . $PSScriptRoot\0_Shared.ps1 # [!build-include-inline] - #Create Unattend for VHD + #Create Unattend for VHD Function CreateUnattendFileVHD{ param ( [parameter(Mandatory=$true)] @@ -72,8 +72,8 @@ If (-not $isAdmin) { true - true - true + true + true $TimeZone @@ -85,7 +85,7 @@ If (-not $isAdmin) { Set-Content -path $unattendFile -value $fileContent #return the file object - Return $unattendFile + Return $unattendFile } #endregion @@ -142,7 +142,7 @@ If (-not $isAdmin) { $LabConfig.DomainName.Split(".") | ForEach-Object { $DN+="DC=$_," } - + $LabConfig.DN=$DN.TrimEnd(",") $AdminPassword=$LabConfig.AdminPassword @@ -158,7 +158,7 @@ If (-not $isAdmin) { #DCHP scope $DHCPscope = $LabConfig.DHCPscope $ReverseDNSrecord = $DHCPscope -replace '^(\d+)\.(\d+)\.\d+\.(\d+)$','$3.$2.$1.in-addr.arpa' - $DHCPscope = $DHCPscope.Substring(0,$DHCPscope.Length-1) + $DHCPscope = $DHCPscope.Substring(0,$DHCPscope.Length-1) #endregion @@ -191,7 +191,7 @@ If (-not $isAdmin) { if(!(Test-Path -Path "$PSScriptRoot\$_")){ WriteErrorAndExit "file $_ needed for SCVMM install not found. Exitting" } - } + } } if ($LabConfig.InstallSCVMM -eq "Prereqs"){ @@ -199,16 +199,16 @@ If (-not $isAdmin) { if(!(Test-Path -Path "$PSScriptRoot\$_")){ WriteErrorAndExit "file $_ needed for SCVMM Prereqs install not found. Exitting" } - } + } } - + if ($LabConfig.InstallSCVMM -eq "SQL"){ "Temp\ToolsVHD\SCVMM\ADK\ADKsetup.exe","Temp\ToolsVHD\SCVMM\SQL\setup.exe" | ForEach-Object { if(!(Test-Path -Path "$PSScriptRoot\$_")){ WriteErrorAndExit "file $_ needed for SQL install not found. Exitting" } } - } + } if ($LabConfig.InstallSCVMM -eq "ADK"){ "Temp\ToolsVHD\SCVMM\ADK\ADKsetup.exe" | ForEach-Object { @@ -221,7 +221,7 @@ If (-not $isAdmin) { #check if parent images already exist (this is useful if you have parent disks from another lab and you want to rebuild for example scvmm) WriteInfoHighlighted "Testing if some parent disk already exists and can be used" - + #grab all files in parentdisks folder $ParentDisksNames=(Get-ChildItem -Path "$PSScriptRoot\ParentDisks" -ErrorAction SilentlyContinue).Name @@ -245,7 +245,7 @@ If (-not $isAdmin) { WriteInfoHighlighted "Checking if volume filesystem is NTFS or ReFS" $driveletter=$PSScriptRoot -split ":" | Select-Object -First 1 if ($PSScriptRoot -like "c:\ClusterStorage*"){ - WriteSuccess "`t Volume Cluster Shared Volume. Mountdir will be $env:Temp\MSLabMountdir" + WriteSuccess "`t Volume Cluster Shared Volume. Mountdir will be $env:Temp\MSLabMountdir" $mountdir="$env:Temp\MSLabMountdir" $VolumeFileSystem="CSVFS" }else{ @@ -279,10 +279,10 @@ If (-not $isAdmin) { $openFile = New-Object System.Windows.Forms.OpenFileDialog -Property @{ Title="Please select ISO image with Windows Server 2016, 2019, 2022 or Server Insider" } - $openFile.Filter = "iso files (*.iso)|*.iso|All files (*.*)|*.*" + $openFile.Filter = "iso files (*.iso)|*.iso|All files (*.*)|*.*" If($openFile.ShowDialog() -eq "OK"){ WriteInfo "File $($openfile.FileName) selected" - } + } if (!$openFile.FileName){ WriteErrorAndExit "Iso was not selected... Exitting" } @@ -332,7 +332,7 @@ If (-not $isAdmin) { Multiselect = $true; Title = "Please select Windows Server Updates (*.msu). Click Cancel if you don't want any." } - $msupackages.Filter = "msu files (*.msu)|*.msu|All files (*.*)|*.*" + $msupackages.Filter = "msu files (*.msu)|*.msu|All files (*.*)|*.*" If($msupackages.ShowDialog() -eq "OK"){ WriteInfoHighlighted "Following patches selected:" WriteInfo "`t $($msupackages.filenames)" @@ -352,13 +352,13 @@ If (-not $isAdmin) { #Windows Server 2016 $ServerVHDs += @{ Kind = "Full" - Edition="4" + Edition="4" VHDName="Win2016_G2.vhdx" Size=127GB } $ServerVHDs += @{ Kind = "Core" - Edition="3" + Edition="3" VHDName="Win2016Core_G2.vhdx" Size=127GB } @@ -374,13 +374,13 @@ If (-not $isAdmin) { #Windows Server 2019 $ServerVHDs += @{ Kind = "Full" - Edition="4" + Edition="4" VHDName="Win2019_G2.vhdx" Size=127GB } $ServerVHDs += @{ Kind = "Core" - Edition="3" + Edition="3" VHDName="Win2019Core_G2.vhdx" Size=127GB } @@ -388,20 +388,20 @@ If (-not $isAdmin) { #Windows Server 2022 $ServerVHDs += @{ Kind = "Full" - Edition="4" + Edition="4" VHDName="Win2022_G2.vhdx" Size=127GB } $ServerVHDs += @{ Kind = "Core" - Edition="3" + Edition="3" VHDName="Win2022Core_G2.vhdx" Size=127GB } }elseif ($BuildNumber -gt 20348 -and $SAC){ $ServerVHDs += @{ Kind = "Core" - Edition="2" + Edition="2" VHDName="WinSrvInsiderCore_$BuildNumber.vhdx" Size=127GB } @@ -413,13 +413,13 @@ If (-not $isAdmin) { #Windows Sever Insider $ServerVHDs += @{ Kind = "Full" - Edition="4" + Edition="4" VHDName="WinSrvInsider_$BuildNumber.vhdx" Size=127GB } $ServerVHDs += @{ Kind = "Core" - Edition="3" + Edition="3" VHDName="WinSrvInsiderCore_$BuildNumber.vhdx" Size=127GB } @@ -450,7 +450,7 @@ If (-not $isAdmin) { 'ParentDisks','Temp','Temp\mountdir' | ForEach-Object { if (!( Test-Path "$PSScriptRoot\$_" )) { WriteInfoHighlighted "Creating Directory $_" - New-Item -Type Directory -Path "$PSScriptRoot\$_" + New-Item -Type Directory -Path "$PSScriptRoot\$_" } } @@ -528,8 +528,8 @@ If (-not $isAdmin) { $toolsVHD=New-VHD -Path "$PSScriptRoot\ParentDisks\tools.vhdx" -SizeBytes 300GB -Dynamic #mount and format VHD $VHDMount = Mount-VHD $toolsVHD.Path -Passthru - $vhddisk = $VHDMount| get-disk - $vhddiskpart = $vhddisk | Initialize-Disk -PartitionStyle GPT -PassThru | New-Partition -UseMaximumSize -AssignDriveLetter |Format-Volume -FileSystem NTFS -AllocationUnitSize 8kb -NewFileSystemLabel ToolsDisk + $vhddisk = $VHDMount| get-disk + $vhddiskpart = $vhddisk | Initialize-Disk -PartitionStyle GPT -PassThru | New-Partition -UseMaximumSize -AssignDriveLetter |Format-Volume -FileSystem NTFS -AllocationUnitSize 8kb -NewFileSystemLabel ToolsDisk $VHDPathTest=Test-Path -Path "$PSScriptRoot\Temp\ToolsVHD\" if (!$VHDPathTest){ @@ -539,7 +539,7 @@ If (-not $isAdmin) { WriteInfo "Found $PSScriptRoot\Temp\ToolsVHD\*, copying files into VHDX" Copy-Item -Path "$PSScriptRoot\Temp\ToolsVHD\*" -Destination "$($vhddiskpart.DriveLetter):\" -Recurse -Force }else{ - WriteInfo "Files not found" + WriteInfo "Files not found" WriteInfoHighlighted "Add required tools into $PSScriptRoot\Temp\ToolsVHD and Press any key to continue..." $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") | OUT-NULL Copy-Item -Path "$PSScriptRoot\Temp\ToolsVHD\*" -Destination ($vhddiskpart.DriveLetter+':\') -Recurse -Force @@ -632,7 +632,7 @@ If (-not $isAdmin) { New-item -type directory -Path $mountdir -force [System.Version]$VMVersion=(Get-WindowsImage -ImagePath $VHDPath -Index 1).Version Mount-WindowsImage -Path $mountdir -ImagePath $VHDPath -Index 1 - Use-WindowsUnattend -Path $mountdir -UnattendPath $unattendFile + Use-WindowsUnattend -Path $mountdir -UnattendPath $unattendFile #&"$PSScriptRoot\Temp\dism\dism" /mount-image /imagefile:$vhdpath /index:1 /MountDir:$mountdir #&"$PSScriptRoot\Temp\dism\dism" /image:$mountdir /Apply-Unattend:$unattendfile New-item -type directory -Path "$mountdir\Windows\Panther" -force @@ -650,12 +650,12 @@ If (-not $isAdmin) { #Create DSC configuration configuration DCHydration { - param - ( - [Parameter(Mandatory)] - [pscredential]$safemodeAdministratorCred, - - [Parameter(Mandatory)] + param + ( + [Parameter(Mandatory)] + [pscredential]$safemodeAdministratorCred, + + [Parameter(Mandatory)] [pscredential]$domainCred, [Parameter(Mandatory)] @@ -670,12 +670,12 @@ If (-not $isAdmin) { Import-DSCResource -ModuleName xPSDesiredStateConfiguration -ModuleVersion "8.10.0.0" Import-DscResource -ModuleName PSDesiredStateConfiguration - Node $AllNodes.Where{$_.Role -eq "Parent DC"}.Nodename + Node $AllNodes.Where{$_.Role -eq "Parent DC"}.Nodename { - WindowsFeature ADDSInstall - { - Ensure = "Present" + WindowsFeature ADDSInstall + { + Ensure = "Present" Name = "AD-Domain-Services" } @@ -691,47 +691,47 @@ If (-not $isAdmin) { Ensure = "Present" Name = "RSAT-AD-PowerShell" DependsOn = "[WindowsFeature]ADDSInstall" - } + } WindowsFeature FeatureADAdminCenter { Ensure = "Present" Name = "RSAT-AD-AdminCenter" DependsOn = "[WindowsFeature]ADDSInstall" - } + } WindowsFeature FeatureADDSTools { Ensure = "Present" Name = "RSAT-ADDS-Tools" DependsOn = "[WindowsFeature]ADDSInstall" - } + } WindowsFeature FeatureDNSTools { Ensure = "Present" Name = "RSAT-DNS-Server" DependsOn = "[WindowsFeature]ADDSInstall" - } - - xADDomain FirstDS - { - DomainName = $Node.DomainName - DomainAdministratorCredential = $domainCred + } + + xADDomain FirstDS + { + DomainName = $Node.DomainName + DomainAdministratorCredential = $domainCred SafemodeAdministratorPassword = $safemodeAdministratorCred DomainNetbiosName = $node.DomainNetbiosName DependsOn = "[WindowsFeature]ADDSInstall" } - - xWaitForADDomain DscForestWait - { - DomainName = $Node.DomainName - DomainUserCredential = $domainCred - RetryCount = $Node.RetryCount - RetryIntervalSec = $Node.RetryIntervalSec - DependsOn = "[xADDomain]FirstDS" + + xWaitForADDomain DscForestWait + { + DomainName = $Node.DomainName + DomainUserCredential = $domainCred + RetryCount = $Node.RetryCount + RetryIntervalSec = $Node.RetryIntervalSec + DependsOn = "[xADDomain]FirstDS" } - + xADOrganizationalUnit DefaultOU { Name = $Node.DefaultOUName @@ -739,7 +739,7 @@ If (-not $isAdmin) { ProtectedFromAccidentalDeletion = $true Description = 'Default OU for all user and computer accounts' Ensure = 'Present' - DependsOn = "[xADDomain]FirstDS" + DependsOn = "[xADDomain]FirstDS" } xADUser SQL_SA @@ -851,7 +851,7 @@ If (-not $isAdmin) { Ensure = "Present" Name = "RSAT-DHCP" DependsOn = "[WindowsFeature]DHCPServer" - } + } xDhcpServerScope ManagementScope @@ -878,7 +878,7 @@ If (-not $isAdmin) { Router = ($DHCPscope+"1") DependsOn = "[Service]DHCPServer" } - + xDhcpServerAuthorization LocalServerActivation { Ensure = 'Present' @@ -913,7 +913,7 @@ If (-not $isAdmin) { State = "Started" DependsOn = "[WindowsFeature]DSCServiceFeature" } - + File RegistrationKeyFile { Ensure = 'Present' @@ -925,12 +925,12 @@ If (-not $isAdmin) { } } - $ConfigData = @{ - - AllNodes = @( - @{ - Nodename = $DCName - Role = "Parent DC" + $ConfigData = @{ + + AllNodes = @( + @{ + Nodename = $DCName + Role = "Parent DC" DomainAdminName=$LabConfig.DomainAdminName DomainName = $LabConfig.DomainName DomainNetbiosName = $LabConfig.DomainNetbiosName @@ -938,15 +938,15 @@ If (-not $isAdmin) { DefaultOUName=$LabConfig.DefaultOUName RegistrationKey='14fc8e72-5036-4e79-9f89-5382160053aa' PSDscAllowPlainTextPassword = $true - PsDscAllowDomainUser= $true - RetryCount = 50 - RetryIntervalSec = 30 - } - ) - } + PsDscAllowDomainUser= $true + RetryCount = 50 + RetryIntervalSec = 30 + } + ) + } #create LCM config - [DSCLocalConfigurationManager()] + [DSCLocalConfigurationManager()] configuration LCMConfig { Node DC @@ -954,7 +954,7 @@ If (-not $isAdmin) { Settings { RebootNodeIfNeeded = $true - ActionAfterReboot = 'ContinueConfiguration' + ActionAfterReboot = 'ContinueConfiguration' } } } @@ -963,7 +963,7 @@ If (-not $isAdmin) { WriteInfoHighlighted "`t Creating DSC Configs for DC" LCMConfig -OutputPath "$PSScriptRoot\Temp\config" -ConfigurationData $ConfigData DCHydration -OutputPath "$PSScriptRoot\Temp\config" -ConfigurationData $ConfigData -safemodeAdministratorCred $cred -domainCred $cred -NewADUserCred $cred - + #copy DSC MOF files to DC WriteInfoHighlighted "`t Copying DSC configurations (pending.mof and metaconfig.mof)" New-item -type directory -Path "$PSScriptRoot\Temp\config" -ErrorAction Ignore @@ -979,7 +979,7 @@ If (-not $isAdmin) { WriteInfoHighlighted "`t Starting DC" $DC | Start-VM - $VMStartupTime = 250 + $VMStartupTime = 250 WriteInfoHighlighted "`t Configuring DC using DSC takes a while." WriteInfo "`t `t Initial configuration in progress. Sleeping $VMStartupTime seconds" Start-Sleep $VMStartupTime @@ -991,7 +991,7 @@ If (-not $isAdmin) { Start-Sleep 10 }elseif ($test.status -ne "Success" -and $i -eq 1) { WriteInfo "`t `t Current DSC state: $($test.status), ResourncesNotInDesiredState: $($test.resourcesNotInDesiredState.count), ResourncesInDesiredState: $($test.resourcesInDesiredState.count)." - WriteInfoHighlighted "`t `t Invoking DSC Configuration again" + WriteInfoHighlighted "`t `t Invoking DSC Configuration again" Invoke-Command -VMGuid $DC.id -ScriptBlock {Start-DscConfiguration -UseExisting} -Credential $cred $i++ }elseif ($test.status -ne "Success" -and $i -gt 1) { @@ -1000,7 +1000,7 @@ If (-not $isAdmin) { Invoke-Command -VMGuid $DC.id -ScriptBlock {Restart-Computer} -Credential $cred }elseif ($test.status -eq "Success" ) { WriteInfo "`t `t Current DSC state: $($test.status), ResourncesNotInDesiredState: $($test.resourcesNotInDesiredState.count), ResourncesInDesiredState: $($test.resourcesInDesiredState.count)." - WriteInfoHighlighted "`t `t DSC Configured DC Successfully" + WriteInfoHighlighted "`t `t DSC Configured DC Successfully" } }until ($test.Status -eq 'Success' -and $test.rebootrequested -eq $false) $test @@ -1010,7 +1010,7 @@ If (-not $isAdmin) { Param($LabConfig); redircmp "OU=$($LabConfig.DefaultOUName),$($LabConfig.DN)" Add-DnsServerPrimaryZone -NetworkID ($DHCPscope+"/24") -ReplicationScope "Forest" - } + } #install SCVMM or its prereqs if specified so if (($LabConfig.InstallSCVMM -eq "Yes") -or ($LabConfig.InstallSCVMM -eq "SQL") -or ($LabConfig.InstallSCVMM -eq "ADK") -or ($LabConfig.InstallSCVMM -eq "Prereqs")){ $DC | Add-VMHardDiskDrive -Path $toolsVHD.Path @@ -1043,7 +1043,7 @@ If (-not $isAdmin) { Start-Sleep 30 #Wait as sometimes VMM failed to install without this. Invoke-Command -VMGuid $DC.id -Credential $cred -ScriptBlock { Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope Process -Force - d:\scvmm\3_SCVMM_Install.ps1 + d:\scvmm\3_SCVMM_Install.ps1 } } @@ -1051,7 +1051,7 @@ If (-not $isAdmin) { WriteInfoHighlighted "Installing SQL" Invoke-Command -VMGuid $DC.id -Credential $cred -ScriptBlock { Set-ExecutionPolicy -ExecutionPolicy Unrestricted -Scope Process -Force - d:\scvmm\1_SQL_Install.ps1 + d:\scvmm\1_SQL_Install.ps1 } } @@ -1084,7 +1084,7 @@ If (-not $isAdmin) { #cleanup DC if (-not $DCFilesExists){ WriteInfoHighlighted "Backup DC and cleanup" - #shutdown DC + #shutdown DC WriteInfo "`t Disconnecting VMNetwork Adapter from DC" $DC | Get-VMNetworkAdapter | Disconnect-VMNetworkAdapter WriteInfo "`t Shutting down DC" @@ -1120,7 +1120,7 @@ If (-not $isAdmin) { <# 0 #> New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", "Cleanup .\Temp\ 1_Prereq.ps1 2_CreateParentDisks.ps1 and rename 3_deploy.ps1 to just deploy.ps1" <# 1 #> New-Object System.Management.Automation.Host.ChoiceDescription "&No", "Keep files (in case DC was not created sucessfully)" ) - + If (!$LabConfig.AutoCleanUp) { $response = $host.UI.PromptForChoice("Unnecessary files cleanup","Do you want to cleanup unnecessary files and folders?", $options, 0 <#default option#>) } @@ -1134,11 +1134,11 @@ If (-not $isAdmin) { }else{ $renamed = $true WriteInfo "`t `t Cleaning unnecessary items" - Remove-Item -Path "$PSScriptRoot\temp" -Force -Recurse + Remove-Item -Path "$PSScriptRoot\temp" -Force -Recurse "$PSScriptRoot\Temp","$PSScriptRoot\1_Prereq.ps1","$PSScriptRoot\2_CreateParentDisks.ps1" | ForEach-Object { WriteInfo "`t `t `t Removing $_" Remove-Item -Path $_ -Force -Recurse -ErrorAction SilentlyContinue - } + } WriteInfo "`t `t `t Renaming $PSScriptRoot\3_Deploy.ps1 to Deploy.ps1" Rename-Item -Path "$PSScriptRoot\3_Deploy.ps1" -NewName "Deploy.ps1" -ErrorAction SilentlyContinue } @@ -1198,13 +1198,13 @@ If (-not $isAdmin) { $vhdProperties['vhd.os.language'] = $OSLanguage } } - $events += New-TelemetryEvent -Event "CreateParentDisks.Vhd" -Metrics $vhdMetrics -Properties $vhdProperties -NickName $LabConfig.TelemetryNickName + $events += Initialize-TelemetryEvent -Event "CreateParentDisks.Vhd" -Metrics $vhdMetrics -Properties $vhdProperties -NickName $LabConfig.TelemetryNickName } # and one overall - $events += New-TelemetryEvent -Event "CreateParentDisks.End" -Metrics $metrics -Properties $properties -NickName $LabConfig.TelemetryNickName + $events += Initialize-TelemetryEvent -Event "CreateParentDisks.End" -Metrics $metrics -Properties $properties -NickName $LabConfig.TelemetryNickName - Send-TelemetryEvents -Events $events | Out-Null + Send-TelemetryEvent -Events $events | Out-Null } Stop-Transcript diff --git a/Scripts/3_Deploy.ps1 b/Scripts/3_Deploy.ps1 index 0abf18f8..e36aa092 100644 --- a/Scripts/3_Deploy.ps1 +++ b/Scripts/3_Deploy.ps1 @@ -4,9 +4,9 @@ If (-not $isAdmin) { Write-Host "-- Restarting as Administrator" -ForegroundColor Cyan ; Start-Sleep -Seconds 1 if($PSVersionTable.PSEdition -eq "Core") { - Start-Process pwsh.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs + Start-Process pwsh.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs } else { - Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs + Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs } exit @@ -58,8 +58,8 @@ If (-not $isAdmin) { true - true - true + true + true $TimeZone @@ -74,7 +74,7 @@ If (-not $isAdmin) { $RunSynchronous - + @@ -82,11 +82,11 @@ If (-not $isAdmin) { Set-Content $unattendFile $fileContent #return the file object - $unattendFile + $unattendFile } Function CreateUnattendFileNoDjoin{ - #Create Unattend(without domain join) + #Create Unattend(without domain join) param ( [parameter(Mandatory=$true)] [string] @@ -136,8 +136,8 @@ If (-not $isAdmin) { true - true - true + true + true $TimeZone @@ -148,7 +148,7 @@ If (-not $isAdmin) { Set-Content $unattendFile $fileContent #return the file object - $unattendFile + $unattendFile } Function CreateUnattendFileWin2012{ @@ -210,8 +210,8 @@ If (-not $isAdmin) { true - true - true + true + true $TimeZone @@ -222,7 +222,7 @@ If (-not $isAdmin) { Set-Content $unattendFile $fileContent #return the file object - $unattendFile + $unattendFile } Function AdditionalLocalAccountXML{ @@ -251,10 +251,10 @@ If (-not $isAdmin) { "@ } - function Get-WindowsBuildNumber { + function Get-WindowsBuildNumber { $os = Get-CimInstance -ClassName Win32_OperatingSystem - return [int]($os.BuildNumber) - } + return [int]($os.BuildNumber) + } Function Set-VMNetworkConfiguration { #source:http://www.ravichaganti.com/blog/?p=2766 with some changes @@ -297,7 +297,7 @@ If (-not $isAdmin) { [Switch]$Dhcp ) - $VM = Get-CimInstance -Namespace "root\virtualization\v2" -ClassName "Msvm_ComputerSystem" | Where-Object ElementName -eq $NetworkAdapter.VMName + $VM = Get-CimInstance -Namespace "root\virtualization\v2" -ClassName "Msvm_ComputerSystem" | Where-Object ElementName -eq $NetworkAdapter.VMName $VMSettings = Get-CimAssociatedInstance -InputObject $vm -ResultClassName "Msvm_VirtualSystemSettingData" | Where-Object VirtualSystemType -EQ "Microsoft:Hyper-V:System:Realized" $VMNetAdapters = Get-CimAssociatedInstance -InputObject $VMSettings -ResultClassName "Msvm_SyntheticEthernetPortSettingData" @@ -339,7 +339,7 @@ If (-not $isAdmin) { } function WrapProcess{ - #Using this function you can run legacy program and search in output string + #Using this function you can run legacy program and search in output string #Example: WrapProcess -filename fltmc.exe -arguments "attach svhdxflt e:" -outputstring "Success" [CmdletBinding()] [Alias()] @@ -382,11 +382,11 @@ If (-not $isAdmin) { # test if process is still running if(!$process.HasExited){ do{ - Start-Sleep 1 + Start-Sleep 1 }until ($process.HasExited -eq $true) } - # get output + # get output $out = $process.StandardOutput.ReadToEnd() if ($out.Contains($outputstring)) { @@ -408,7 +408,7 @@ If (-not $isAdmin) { WriteInfoHighlighted "Creating VM $($VMConfig.VMName)" WriteInfo "`t Looking for Parent Disk" $serverparent = Get-ChildItem "$PSScriptRoot\ParentDisks\" -Recurse | Where-Object Name -eq $VMConfig.ParentVHD - + if ($serverparent -eq $null) { WriteErrorAndExit "Server parent disk $($VMConfig.ParentVHD) not found." }else{ @@ -423,7 +423,7 @@ If (-not $isAdmin) { } WriteInfo "`t Creating OS VHD" New-VHD -ParentPath $serverparent.fullname -Path $vhdpath - + $VMTemp = New-VM -Path "$LabFolder\VMs" -Name $VMname -Generation 2 -MemoryStartupBytes $VMConfig.MemoryStartupBytes -SwitchName $SwitchName -VHDPath $vhdPath #Set dynamic memory @@ -439,16 +439,16 @@ If (-not $isAdmin) { $VMTemp | Set-VM -AutomaticCheckpointsEnabled $False } $VMTemp | Set-VMFirmware -EnableSecureBoot Off - + # only Debian Buster supports Secure Boot #$vm | Set-VMFirmware -EnableSecureBoot On -SecureBootTemplateId "272e7447-90a4-4563-a4b9-8e4ab00526ce" # -SecureBootTemplate MicrosoftUEFICertificateAuthority - + Start-VM $VMTemp # wait for the IP address Write-Host "`t Waiting for network connectivity to the VM..." -NoNewLine $count = 0 - do { + do { $ip = $VMTemp | Get-VMNetworkAdapter | Select-Object -ExpandProperty IPAddresses Start-Sleep -Seconds 1 @@ -485,12 +485,12 @@ If (-not $isAdmin) { if(-not $VMConfig.LinuxDomainJoin -or $VMConfig.LinuxDomainJoin.ToLower() -eq "sssd") { WriteInfo "`t Creating AD Computer object..." Invoke-Command -VMGuid $DC.id -Credential $cred -ArgumentList $VMConfig.VMName,$path,$Labconfig -ScriptBlock { - param($Name,$path,$Labconfig); + param($Name,$path,$Labconfig); New-ADComputer -Name $Name -Path "OU=$($Labconfig.DefaultOUName),$($Labconfig.DN)" $password = ConvertTo-SecureString -String $Name -AsPlainText -Force Get-ADComputer -Identity $Name | Set-ADAccountPassword -NewPassword:$password -Reset:$true - } + } WriteInfo "`t Joining to AD..." $upn = ("$(($LabConfig.DomainAdminName).ToLower())@$($LabConfig.DomainName)") @@ -503,12 +503,12 @@ If (-not $isAdmin) { # Wait for vm to shut down $count = 0 - do { + do { $vm = $VMTemp | Get-VM Start-Sleep -Seconds 1 $count += 1 } while ($vm.State -ne "Off" -and $count -le 60) - + if($vm.State -ne "Off") { $VMTemp | Stop-VM } @@ -530,7 +530,7 @@ If (-not $isAdmin) { WriteInfoHighlighted "Creating VM $($VMConfig.VMName)" WriteInfo "`t Looking for Parent Disk" $serverparent=Get-ChildItem "$PSScriptRoot\ParentDisks\" -Recurse | Where-Object Name -eq $VMConfig.ParentVHD - + if ($serverparent -eq $null){ WriteErrorAndExit "Server parent disk $($VMConfig.ParentVHD) not found." }else{ @@ -554,7 +554,7 @@ If (-not $isAdmin) { if ($VMConfig.Generation -eq 1){ $VMTemp=New-VM -Name $VMname -VHDPath $vhdpath -MemoryStartupBytes $VMConfig.MemoryStartupBytes -path "$LabFolder\VMs" -SwitchName $SwitchName -Generation 1 }else{ - $VMTemp=New-VM -Name $VMname -VHDPath $vhdpath -MemoryStartupBytes $VMConfig.MemoryStartupBytes -path "$LabFolder\VMs" -SwitchName $SwitchName -Generation 2 + $VMTemp=New-VM -Name $VMname -VHDPath $vhdpath -MemoryStartupBytes $VMConfig.MemoryStartupBytes -path "$LabFolder\VMs" -SwitchName $SwitchName -Generation 2 } $VMTemp | Set-VMMemory -DynamicMemoryEnabled $true $VMTemp | Get-VMNetworkAdapter | Rename-VMNetworkAdapter -NewName Management1 @@ -805,7 +805,7 @@ If (-not $isAdmin) { if ($unattendFile){ WriteInfo "`t Adding unattend to VHD" Mount-WindowsImage -Path $mountdir -ImagePath $VHDPath -Index 1 - Use-WindowsUnattend -Path $mountdir -UnattendPath $unattendFile + Use-WindowsUnattend -Path $mountdir -UnattendPath $unattendFile #&"$PSScriptRoot\Tools\dism\dism" /mount-image /imagefile:$vhdpath /index:1 /MountDir:$mountdir #&"$PSScriptRoot\Tools\dism\dism" /image:$mountdir /Apply-Unattend:$unattendfile New-item -type directory "$mountdir\Windows\Panther" -ErrorAction Ignore @@ -863,7 +863,6 @@ If (-not $isAdmin) { } Send-TelemetryEvent -Event "Deploy.Start" -NickName $LabConfig.TelemetryNickName | Out-Null } - #endregion #region Set variables @@ -904,7 +903,7 @@ If (-not $isAdmin) { WriteInfo "`t Prefix used in lab is $($labconfig.prefix)" $SwitchName=($labconfig.prefix+$LabConfig.SwitchName) - WriteInfo "`t Switchname is $SwitchName" + WriteInfo "`t Switchname is $SwitchName" WriteInfo "`t Workdir is $PSScriptRoot" @@ -922,7 +921,7 @@ If (-not $isAdmin) { Get-CimInstance -ClassName "win32_processor" | ForEach-Object { $global:NumberOfLogicalProcessors += $_.NumberOfLogicalProcessors } #Calculate highest VLAN (for additional subnets) - [int]$HighestVLAN=$LabConfig.AllowedVLANs -split "," -split "-" | Select -Last 1 + [int]$HighestVLAN=$LabConfig.AllowedVLANs -split "," -split "-" | Select-Object -Last 1 #Grab defined Management Subnet IDs and ignore 0 $ManagementSubnetIDs=$labconfig.vms.ManagementSubnetID + $LabConfig.ManagementSubnetIDs | Select-Object -Unique | Sort-Object | Where-Object {$_ -ne 0} @@ -991,7 +990,7 @@ If (-not $isAdmin) { WriteInfo "`t Installing Failover Clustering Feature" $FC=Install-WindowsFeature Failover-Clustering If ($FC.Success -eq $True){ - WriteSuccess "`t`t Failover Clustering Feature installed with exit code: $($FC.ExitCode)" + WriteSuccess "`t`t Failover Clustering Feature installed with exit code: $($FC.ExitCode)" }else{ WriteError "`t`t Failover Clustering Feature was not installed with exit code: $($FC.ExitCode)" } @@ -1008,10 +1007,10 @@ If (-not $isAdmin) { } } - WriteInfoHighlighted "Adding svhdxflt to registry for autostart" + WriteInfoHighlighted "Adding svhdxflt to registry for autostart" if (!(Test-Path HKLM:\SYSTEM\CurrentControlSet\Services\svhdxflt\Parameters)){ New-Item HKLM:\SYSTEM\CurrentControlSet\Services\svhdxflt\Parameters - } + } New-ItemProperty -Path HKLM:\SYSTEM\CurrentControlSet\Services\svhdxflt\Parameters -Name AutoAttachOnNonCSVVolumes -PropertyType DWORD -Value 1 -force } @@ -1043,7 +1042,7 @@ If (-not $isAdmin) { WriteInfoHighlighted "Checking if volume filesystem is NTFS or ReFS" $driveletter=$PSScriptRoot -split ":" | Select-Object -First 1 if ($PSScriptRoot -like "c:\ClusterStorage*"){ - WriteSuccess "`t Volume Cluster Shared Volume. Mountdir will be $env:Temp\MSLabMountdir" + WriteSuccess "`t Volume Cluster Shared Volume. Mountdir will be $env:Temp\MSLabMountdir" $mountdir="$env:Temp\MSLabMountDir" $VolumeFileSystem="CSVFS" }else{ @@ -1068,7 +1067,7 @@ If (-not $isAdmin) { WriteInfoHighlighted "Creating Switch" WriteInfo "`t Checking if $SwitchName already exists..." - if (-not (Get-VMSwitch -Name $SwitchName -ErrorAction Ignore)){ + if (-not (Get-VMSwitch -Name $SwitchName -ErrorAction Ignore)){ WriteInfo "`t Creating $SwitchName..." if ($LabConfig.SwitchNICs){ #test if NICs are not already connected to another switch @@ -1144,7 +1143,7 @@ If (-not $isAdmin) { if ($TempNetAdapters.name.count -gt 1){ WriteInfo "`t More than 1 NIC detected" WriteInfoHighlighted "`t Please select NetAdapter you want to use for vSwitch" - $tempNetAdapter=get-netadapter | Where-Object Name -NotLike vEthernet* | Where-Object status -eq up | Out-GridView -OutputMode Single -Title "Please select adapter you want to use for External vSwitch" + $tempNetAdapter=get-netadapter | Where-Object Name -NotLike vEthernet* | Where-Object status -eq up | Out-GridView -OutputMode Single -Title "Please select adapter you want to use for External vSwitch" if (!$tempNetAdapter){ WriteErrorAndExit "You did not select any net adapter. Exitting." } @@ -1204,8 +1203,8 @@ If (-not $isAdmin) { $toolsVHD=New-VHD -Path "$PSScriptRoot\ParentDisks\tools.vhdx" -SizeBytes 30GB -Dynamic #mount and format VHD $VHDMount = Mount-VHD $toolsVHD.Path -Passthru - $vhddisk = $VHDMount| get-disk - $vhddisk | Initialize-Disk -PartitionStyle GPT -PassThru | New-Partition -UseMaximumSize -AssignDriveLetter |Format-Volume -FileSystem NTFS -AllocationUnitSize 8kb -NewFileSystemLabel ToolsDisk + $vhddisk = $VHDMount| get-disk + $vhddisk | Initialize-Disk -PartitionStyle GPT -PassThru | New-Partition -UseMaximumSize -AssignDriveLetter |Format-Volume -FileSystem NTFS -AllocationUnitSize 8kb -NewFileSystemLabel ToolsDisk #dismount VHD Dismount-VHD $vhddisk.Number }else{ @@ -1272,7 +1271,7 @@ If (-not $isAdmin) { $DC | Add-VMNetworkAdapter -SwitchName $SwitchName -Name $AdditionalNetworkConfig.NetName WriteInfo "`t`t Adding Adapter $($AdditionalNetworkConfig.NetName) with IP $($AdditionalNetworkConfig.NetAddress)$global:IP" $DC | Get-VMNetworkAdapter -Name $AdditionalNetworkConfig.NetName | Set-VMNetworkConfiguration -IPAddress "$($AdditionalNetworkConfig.NetAddress)$global:IP" -Subnet $AdditionalNetworkConfig.Subnet - if($AdditionalNetworkConfig.NetVLAN -ne 0){ + if($AdditionalNetworkConfig.NetVLAN -ne 0){ $DC | Get-VMNetworkAdapter -Name $AdditionalNetworkConfig.NetName | Set-VMNetworkAdapterVlan -VlanId $AdditionalNetworkConfig.NetVLAN -Access } } @@ -1388,7 +1387,7 @@ If (-not $isAdmin) { $IP="192.168.0.$startIP" WriteInfo "`t Configure static IP $IP on Internet NIC" Invoke-Command -VMGuid $DC.id -Credential $cred -ScriptBlock { - $NetAdapterName=(Get-NetAdapterAdvancedProperty | where displayvalue -eq Internet).Name + $NetAdapterName=(Get-NetAdapterAdvancedProperty | Where-Object displayvalue -eq Internet).Name New-NetIPAddress -InterfaceAlias $NetAdapterName -IPAddress $using:IP -PrefixLength 24 -DefaultGateway "192.168.0.1" } } @@ -1513,7 +1512,7 @@ If (-not $isAdmin) { WriteInfoHighlighted "Creating DSC config to configure DC as pull server" [DSCLocalConfigurationManager()] - Configuration PullClientConfig + Configuration PullClientConfig { param ( @@ -1536,7 +1535,7 @@ If (-not $isAdmin) { ActionAfterReboot = 'ContinueConfiguration' } - ConfigurationRepositoryWeb PullServerWeb { + ConfigurationRepositoryWeb PullServerWeb { ServerURL = "http://dc.$($DomainName):8080/PSDSCPullServer.svc" AllowUnsecureConnection = $true RegistrationKey = '14fc8e72-5036-4e79-9f89-5382160053aa' @@ -1573,7 +1572,7 @@ If (-not $isAdmin) { if(-not $VMConfig.MemoryStartupBytes) { $VMConfig.MemoryStartupBytes = 512MB } - + #create VM with Shared configuration if ($VMConfig.configuration -eq 'Shared'){ #create disks (if not already created) @@ -1581,11 +1580,11 @@ If (-not $isAdmin) { if (!(Test-Path -Path "$LABfolder\VMs\*$VMSet*.VHDS")){ $SharedSSDs=$null $SharedHDDs=$null - If (($VMConfig.SSDNumber -ge 1) -and ($VMConfig.SSDNumber -ne $null)){ + If (($VMConfig.SSDNumber -ge 1) -and ($VMConfig.SSDNumber -ne $null)){ $SharedSSDs= 1..$VMConfig.ssdnumber | ForEach-Object {New-vhd -Path "$LABfolder\VMs\SharedSSD-$VMSet-$_.VHDS" -Dynamic -Size $VMConfig.SSDSize} $SharedSSDs | ForEach-Object {WriteInfo "`t Disk SSD $($_.path) size $($_.size /1GB)GB created"} } - If (($VMConfig.HDDNumber -ge 1) -and ($VMConfig.HDDNumber -ne $null)){ + If (($VMConfig.HDDNumber -ge 1) -and ($VMConfig.HDDNumber -ne $null)){ $SharedHDDs= 1..$VMConfig.hddnumber | ForEach-Object {New-VHD -Path "$LABfolder\VMs\SharedHDD-$VMSet-$_.VHDS" -Dynamic -Size $VMConfig.HDDSize} $SharedHDDs | ForEach-Object {WriteInfo "`t Disk HDD $($_.path) size $($_.size /1GB)GB created"} } @@ -1630,7 +1629,7 @@ If (-not $isAdmin) { #Add disks #add "SSDs" - If (($VMConfig.SSDNumber -ge 1) -and ($VMConfig.SSDNumber -ne $null)){ + If (($VMConfig.SSDNumber -ge 1) -and ($VMConfig.SSDNumber -ne $null)){ $SSDs= 1..$VMConfig.SSDNumber | ForEach-Object { New-vhd -Path "$LabFolder\VMs\$VMname\Virtual Hard Disks\SSD-$_.VHDX" -Dynamic -Size $VMConfig.SSDSize} WriteInfoHighlighted "`t Adding Virtual SSD Disks" $SSDs | ForEach-Object { @@ -1651,7 +1650,7 @@ If (-not $isAdmin) { } } - #create VM with Replica configuration + #create VM with Replica configuration if ($VMConfig.configuration -eq 'Replica'){ #create shared drives if not already created $VMSet=$VMConfig.VMSet @@ -1668,7 +1667,7 @@ If (-not $isAdmin) { $createdVm = BuildVM -VMConfig $VMConfig -LabConfig $labconfig -LabFolder $LABfolder #Add disks - $VMname=$Labconfig.Prefix+$VMConfig.VMName + $VMname=$Labconfig.Prefix+$VMConfig.VMName WriteInfoHighlighted "`t Attaching Shared Disks..." #Add HDD $ReplicaHdd | ForEach-Object { @@ -1692,7 +1691,7 @@ If (-not $isAdmin) { } if((Test-Path -Path $createdVm.OSDiskPath) -and $VMConfig.configuration -ne "Linux") { $osInfo = Get-WindowsImage -ImagePath $createdVm.OSDiskPath -Index 1 - + $properties.'vm.os.installationType' = $osInfo.InstallationType $properties.'vm.os.editionId' = $osInfo.EditionId $properties.'vm.os.version' = $osInfo.Version @@ -1701,10 +1700,10 @@ If (-not $isAdmin) { $metrics = @{ 'vm.deploymentDuration' = ((Get-Date) - $vmProvisioningStartTime).TotalSeconds } - $vmInfo = New-TelemetryEvent -Event "Deploy.VM" -Properties $properties -Metrics $metrics -NickName $LabConfig.TelemetryNickName + $vmInfo = Initialize-TelemetryEvent -Event "Deploy.VM" -Properties $properties -Metrics $metrics -NickName $LabConfig.TelemetryNickName $vmDeploymentEvents += $vmInfo } - + $provisionedVMs += $createdVm.VM } } @@ -1712,7 +1711,7 @@ If (-not $isAdmin) { #endregion #region Finishing - WriteInfoHighlighted "Finishing..." + WriteInfoHighlighted "Finishing..." #a bit cleanup Remove-Item -Path "$PSScriptRoot\temp" -Force -Recurse @@ -1721,7 +1720,7 @@ If (-not $isAdmin) { WriteInfo "`t Setting MacSpoofing On and AllowTeaming On" Set-VMNetworkAdapter -VMName "$($labconfig.Prefix)*" -MacAddressSpoofing On -AllowTeaming On - #list VMs + #list VMs $AllVMs = Get-VM | Where-Object name -like "$($labconfig.Prefix)*" $AllVMs | ForEach-Object { WriteSuccess "Machine $($_.VMName) provisioned" } @@ -1732,7 +1731,7 @@ If (-not $isAdmin) { #Enable Guest services on all VMs if integration component if configured if ($labconfig.EnableGuestServiceInterface){ WriteInfo "`t Enabling Guest Service Interface" - $vms = Get-VM -VMName "$($labconfig.Prefix)*" | Where-Object {$_.state -eq "Running" -or $_.state -eq "Off"} + $vms = Get-VM -VMName "$($labconfig.Prefix)*" | Where-Object {$_.state -eq "Running" -or $_.state -eq "Off"} foreach ($vm in $vms) { $guestServiceId = 'Microsoft:{0}\6C09BB55-D683-4DA0-8931-C9BF705F6480' -f $vm.Id $guestService = $vm | Get-VMIntegrationService | Where-Object -FilterScript {$_.Id -eq $guestServiceId} @@ -1764,7 +1763,7 @@ If (-not $isAdmin) { <# 0 #> New-Object System.Management.Automation.Host.ChoiceDescription "&No", "No VM will be started." <# 1 #> New-Object System.Management.Automation.Host.ChoiceDescription "&All", "All VMs in the lab will be started." ) - + if($provisionedVMs.Count -gt 0) { <# 2 #> $options += New-Object System.Management.Automation.Host.ChoiceDescription "&Deployed only", "Only newly deployed VMs will be started." } @@ -1780,10 +1779,10 @@ If (-not $isAdmin) { $toStart = $provisionedVMs } } - + if(($toStart | Measure-Object).Count -gt 0) { WriteInfoHighlighted "Starting VMs" - $toStart | ForEach-Object { + $toStart | ForEach-Object { WriteInfo "`t $($_.Name)" Start-VM -VM $_ -WarningAction SilentlyContinue } @@ -1802,10 +1801,10 @@ If (-not $isAdmin) { 'lab.isncrementalDeployment' = $LABExists 'lab.autostartmode' = $startVMs } - $telemetryEvent = New-TelemetryEvent -Event "Deploy.End" -Metrics $metrics -Properties $properties -NickName $LabConfig.TelemetryNickName + $telemetryEvent = Initialize-TelemetryEvent -Event "Deploy.End" -Metrics $metrics -Properties $properties -NickName $LabConfig.TelemetryNickName $vmDeploymentEvents += $telemetryEvent - Send-TelemetryEvents -Events $vmDeploymentEvents | Out-Null + Send-TelemetryEvent -Events $vmDeploymentEvents | Out-Null } #write how much it took to deploy diff --git a/Scripts/Cleanup.ps1 b/Scripts/Cleanup.ps1 index ea5b5c08..e318a080 100644 --- a/Scripts/Cleanup.ps1 +++ b/Scripts/Cleanup.ps1 @@ -4,9 +4,9 @@ If (-not $isAdmin) { Write-Host "-- Restarting as Administrator" -ForegroundColor Cyan ; Start-Sleep -Seconds 1 if($PSVersionTable.PSEdition -eq "Core") { - Start-Process pwsh.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs + Start-Process pwsh.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs } else { - Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs + Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs } exit @@ -62,7 +62,7 @@ If (-not $isAdmin) { #just one more space WriteInfo "" - # This is only needed if you kill deployment script in middle when it mounts VHD into mountdir. + # This is only needed if you kill deployment script in middle when it mounts VHD into mountdir. if ((Get-ChildItem -Path "$PSScriptRoot\temp\mountdir" -ErrorAction SilentlyContinue)){ Dismount-WindowsImage -Path "$PSScriptRoot\temp\mountdir" -Discard -ErrorAction SilentlyContinue } @@ -105,18 +105,18 @@ If (-not $isAdmin) { WriteInfo "`t Removing vSwitch $($extvSwitch.Name)" $extvSwitch | Remove-VMSwitch -Force } - #Cleanup folders + #Cleanup folders if ((test-path "$PSScriptRoot\LAB\VMs") -or (test-path "$PSScriptRoot\temp") ){ WriteInfoHighlighted "Cleaning folders" "$PSScriptRoot\LAB\VMs","$PSScriptRoot\temp" | ForEach-Object { if ((test-path -Path $_)){ WriteInfo "`t Removing folder $_" remove-item $_ -Confirm:$False -Recurse - } + } } } - #Unzipping configuration files as VM was removed few lines ago-and it deletes vm configuration... + #Unzipping configuration files as VM was removed few lines ago-and it deletes vm configuration... $zipfile = "$PSScriptRoot\LAB\DC\Virtual Machines.zip" $zipoutput = "$PSScriptRoot\LAB\DC\" Microsoft.PowerShell.Archive\Expand-Archive -Path $zipfile -DestinationPath $zipoutput -Force @@ -131,7 +131,7 @@ If (-not $isAdmin) { Send-TelemetryEvent -Event "Cleanup" -Metrics $metrics -NickName $LabConfig.TelemetryNickName | Out-Null } - #finishing + #finishing WriteSuccess "Job Done! Press enter to continue ..." $exit=Read-Host }else { diff --git a/Scripts/LabConfig.ps1 b/Scripts/LabConfig.ps1 index cde81bfc..dfa3efaa 100644 --- a/Scripts/LabConfig.ps1 +++ b/Scripts/LabConfig.ps1 @@ -36,7 +36,7 @@ $LabConfig=@{ DomainAdminName='LabAdmin'; AdminPassword='LS1setup!'; Prefix = 'M ServerMSUsFolder=""; # (Optional) If configured, script will inject all MSU files found into server OS EnableGuestServiceInterface=$false; # (Optional) If True, then Guest Services integration component will be enabled on all VMs. DCVMProcessorCount=2; # (Optional) 2 is default. If specified more/less, processorcount will be modified. - DHCPscope="10.0.0.0"; # (Optional) 10.0.0.0 is configured if nothing is specified. Scope has to end with .0 (like 10.10.10.0). It's always /24 + DHCPscope="10.0.0.0"; # (Optional) 10.0.0.0 is configured if nothing is specified. Scope has to end with .0 (like 10.10.10.0). It's always /24 DCVMVersion="9.0"; # (Optional) Latest is used if nothing is specified. Make sure you use values like "8.0","8.3","9.0" TelemetryLevel=""; # (Optional) If configured, script will stop prompting you for telemetry. Values are "None","Basic","Full" TelemetryNickname=""; # (Optional) If configured, telemetry will be sent with NickName to correlate data to specified NickName. So when leaderboards will be published, MSLab users will be able to see their own stats @@ -53,7 +53,7 @@ $LabConfig=@{ DomainAdminName='LabAdmin'; AdminPassword='LS1setup!'; Prefix = 'M } # Specifying LabVMs - 1..4 | ForEach-Object { + 1..4 | ForEach-Object { $VMNames="S2D"; # Here you can bulk edit name of 4 VMs created. In this case will be s2d1,s2d2,s2d3,s2d4 created $LABConfig.VMs += @{ VMName = "$VMNames$_" ; @@ -68,7 +68,7 @@ $LabConfig=@{ DomainAdminName='LabAdmin'; AdminPassword='LS1setup!'; Prefix = 'M } #optional: (only if AdditionalNetworks are configured in $LabConfig.VMs) this is just an example. In this configuration its not needed. - $LABConfig.AdditionalNetworksConfig += @{ + $LABConfig.AdditionalNetworksConfig += @{ NetName = 'Storage1'; # Network Name NetAddress='172.16.1.'; # Network Addresses prefix. (starts with 1), therefore first VM with Additional network config will have IP 172.16.1.1 NetVLAN='1'; # VLAN tagging @@ -109,7 +109,7 @@ $LabConfig=@{ DomainAdminName='LabAdmin'; AdminPassword='LS1setup!'; Prefix = 'M 'SQL' - installs just SQL 'Prereqs' - installs ADK and SQL 'No' - No, or anything else, nothing is installed. - + *requires install files in toolsVHD\SCVMM\, or it will fail. You can download all tools here: SQL: http://www.microsoft.com/en-us/evalcenter/evaluate-sql-server-2016 SCVMM: http://www.microsoft.com/en-us/evalcenter/evaluate-system-center-technical-preview @@ -145,7 +145,7 @@ $LabConfig=@{ DomainAdminName='LabAdmin'; AdminPassword='LS1setup!'; Prefix = 'M It will add vNIC to DC and configure NAT with some Open DNS servers in DNS forwarder UseHostDnsAsForwarder (Optional) - If $true, local DNS servers will be used as DNS forwarders in DC when Internet is enabled. + If $true, local DNS servers will be used as DNS forwarders in DC when Internet is enabled. By default local host's DNS servers will be used as forwarders. CustomDnsForwarders (Optional) @@ -153,7 +153,7 @@ $LabConfig=@{ DomainAdminName='LabAdmin'; AdminPassword='LS1setup!'; Prefix = 'M If not defined at all, commonly known DNS servers will be used as a fallback: - Google DNS: 8.8.8.8 - Cloudfare: 1.1.1.1 - + DHCPscope (Optional) If configured, a custom DHCP scope will be used. Will always use a '/24'. Specify input like '10.1.0.0' or '192.168.0.0' @@ -196,11 +196,11 @@ $LabConfig=@{ DomainAdminName='LabAdmin'; AdminPassword='LS1setup!'; Prefix = 'M ManagementSubnetIDs Example: ManagementSubnetIDs=0..3 If configured, it will add another management subnet. For example if configured 0..3, it will add 3 more subnets 10.0.1.0/24 to 10.0.3.0/24 on VLANs that 11,12, and 13. (Because allowed VLANs are 1-10) - + Linux (optional) Example: Linux=$true If set to $true, additional prerequisities (SSH Client, SSH Key, Packer, Packer templates) required for building Linux images will be downloaded and configured. - + LinuxAdminName (optional) Example: LinuxAdminName="linuxadmin" If set, local user account with that name will be created in Linux image. If not, DomainAdminName will be used as a local account. @@ -227,7 +227,7 @@ $LabConfig=@{ DomainAdminName='LabAdmin'; AdminPassword='LS1setup!'; Prefix = 'M $LABConfig.VMs += @{ VMName = 'Management' ; Configuration = 'Simple' ; ParentVHD = 'Win10_G2.vhdx' ; MemoryStartupBytes= 1GB ; AddToolsVHD=$True } Multiple: 1..2 | ForEach-Object { $VMNames="Replica" ; $LABConfig.VMs += @{ VMName = "$VMNames$_" ; Configuration = 'Replica' ; ParentVHD = 'Win2016NanoHV_G2.vhdx' ; ReplicaHDDSize = 20GB ; ReplicaLogSize = 10GB ; MemoryStartupBytes= 2GB ; VMSet= 'ReplicaSet1' ; AdditionalNetworks = $True} } - + VMName (Mandatory) Can be whatever. This name will be used as name to djoin VM. @@ -247,7 +247,7 @@ $LabConfig=@{ DomainAdminName='LabAdmin'; AdminPassword='LS1setup!'; Prefix = 'M 'Win10_G2.vhdx' - Windows 10 if you selected to hydrate it with create client parent. AdditionalNetworks (Optional) - $True - Additional networks (configured in AdditonalNetworkConfig) are added + $True - Additional networks (configured in AdditonalNetworkConfig) are added AdditionalNetworkAdapters (Optional) - Hashtable or array if multiple network adapters should be connected to this virtual machine @{ @@ -257,7 +257,7 @@ $LabConfig=@{ DomainAdminName='LabAdmin'; AdminPassword='LS1setup!'; Prefix = 'M IpConfiguration (Optional) - DHCP or hastable with specific IP configuration @{ IpAddress (Mandatory) - Static IP Address that would be injected to the OS - Subnet (Mandatory) + Subnet (Mandatory) } } @@ -278,7 +278,7 @@ $LabConfig=@{ DomainAdminName='LabAdmin'; AdminPassword='LS1setup!'; Prefix = 'M MemoryMinimumBytes (Optional) Example: 1GB Minimum memory bytes, must be less or equal to MemoryStartupBytes - If not set, default is used. + If not set, default is used. StaticMemory (Optional) if $True, then static memory is configured @@ -344,7 +344,7 @@ $LabConfig=@{ DomainAdminName='LabAdmin'; AdminPassword='LS1setup!'; Prefix = 'M ManagementSubnetID (Optional) This will set Management NICs to defined subnet id by configuring native VLAN ID. Default is 0. If configured to 1, it will increase highest allowed VLAN by one and configure. - For example ManagementSubnetID=1, AllowedVlans=10, then ManagementSubnetID VLAN will be configured 11. + For example ManagementSubnetID=1, AllowedVlans=10, then ManagementSubnetID VLAN will be configured 11. #DisableTimeIC (Optional) Example DisableTimeIC=$true @@ -374,9 +374,9 @@ $LabConfig=@{ DomainAdminName='LabAdmin'; AdminPassword='LS1setup!'; Prefix = 'M <# Just some VMs $LabConfig.VMs = @( - @{ VMName = 'Simple1' ; Configuration = 'Simple' ; ParentVHD = 'Win2016NanoHV_G2.vhdx' ; MemoryStartupBytes= 512MB }, - @{ VMName = 'Simple2' ; Configuration = 'Simple' ; ParentVHD = 'Win2016NanoHV_G2.vhdx' ; MemoryStartupBytes= 512MB }, - @{ VMName = 'Simple3' ; Configuration = 'Simple' ; ParentVHD = 'Win2016NanoHV_G2.vhdx' ; MemoryStartupBytes= 512MB }, + @{ VMName = 'Simple1' ; Configuration = 'Simple' ; ParentVHD = 'Win2016NanoHV_G2.vhdx' ; MemoryStartupBytes= 512MB }, + @{ VMName = 'Simple2' ; Configuration = 'Simple' ; ParentVHD = 'Win2016NanoHV_G2.vhdx' ; MemoryStartupBytes= 512MB }, + @{ VMName = 'Simple3' ; Configuration = 'Simple' ; ParentVHD = 'Win2016NanoHV_G2.vhdx' ; MemoryStartupBytes= 512MB }, @{ VMName = 'Simple4' ; Configuration = 'Simple' ; ParentVHD = 'Win2016NanoHV_G2.vhdx' ; MemoryStartupBytes= 512MB } ) @@ -391,7 +391,7 @@ $LabConfig=@{ DomainAdminName='LabAdmin'; AdminPassword='LS1setup!'; Prefix = 'M 1..100 | ForEach-Object {"NanoServer$_"} | ForEach-Object { $LabConfig.VMs += @{ VMName = $_ ; Configuration = 'Simple' ; ParentVHD = 'Win2016NanoHV_G2.vhdx' ; MemoryStartupBytes= 512MB } } 1..100 | ForEach-Object {"Windows10_$_"} | ForEach-Object { $LabConfig.VMs += @{ VMName = $_ ; Configuration = 'Simple' ; ParentVHD = 'Win10_G2.vhdx' ; MemoryStartupBytes= 512MB ; AddToolsVHD=$True ; DisableWCF=$True } } - or Several different VMs + or Several different VMs * you need to provide your GPT VHD for win 2012 (like created with convertwindowsimage script) $LabConfig.VMs += @{ VMName = 'Win10' ; Configuration = 'Simple' ; ParentVHD = 'Win10_G2.vhdx' ; MemoryStartupBytes= 512MB ; DisableWCF=$True ; vTPM=$True ; EnableWinRM=$True } $LabConfig.VMs += @{ VMName = 'Win10_OOBE' ; Configuration = 'Simple' ; ParentVHD = 'Win10_G2.vhdx' ; MemoryStartupBytes= 512MB ; DisableWCF=$True ; vTPM=$True ; Unattend="None" }