diff --git a/Scripts/1_Prereq.ps1 b/Scripts/1_Prereq.ps1
index 25d78dfd..8f5e612d 100644
--- a/Scripts/1_Prereq.ps1
+++ b/Scripts/1_Prereq.ps1
@@ -1,43 +1,39 @@
-# Verify Running as Admin
-$isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")
-If (!( $isAdmin )) {
- Write-Host "-- Restarting as Administrator" -ForegroundColor Cyan ; Sleep -Seconds 1
- Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs
- exit
-}
-
-# Skipping 10 lines because if running when all prereqs met, statusbar covers powershell output
-
+<#
+.Synopsis
+ Preps for the creation of the Lab VMs
+.Description
+ Creates the required directories; downloads the tools diskspd.exe, convert-windowsimage.ps1, and the required DSC resources
+.EXAMPLE
+ .\1_Prereq.ps1
+.EXAMPLE
+ .\1_Prereq.ps1 -verbose
+#>
+#Requires -RunAsAdministrator
+[CmdletBinding()]
+param()
+
+Write-Verbose -Message "Skipping 10 lines because if running when all prereqs met, statusbar covers powershell output"
1..10 |% { Write-Host ""}
-# Functions
-function Get-WindowsBuildNumber {
- $os = Get-WmiObject -Class Win32_OperatingSystem
- return [int]($os.BuildNumber)
-}
+Write-Verbose -Message "Loading Functions"
+. .\functions.ps1
-
-# Get workdirectory and Start Time
-$workdir = Split-Path $script:MyInvocation.MyCommand.Path
-Start-Transcript -Path $workdir'\Prereq.log'
+Write-Verbose -Message "Get workdirectory and Start Time"
+$workdir = Get-ScriptDirectory
+Start-Transcript -Path $workdir'\Prereq.log' -Append
$StartDateTime = get-date
-Write-host "Script started at $StartDateTime"
-
-# Checking for Compatible OS
-Write-Host "Checking if OS is Windows 10 TH2/Server 2016 TP4 or newer" -ForegroundColor Cyan
+Write-Information -MessageData "Script started at $StartDateTime" -InformationAction Continue
+Write-Verbose -Message "Checking if OS is Windows 10 TH2/Server 2016 TP4 or newer"
$BuildNumber=Get-WindowsBuildNumber
if ($BuildNumber -ge 10586){
- Write-Host "`t OS is Windows 10 TH2/Server 2016 TP4 or newer" -ForegroundColor Green
+ Write-Verbose -Message "OS is Windows 10 TH2/Server 2016 TP4 or newer"
}else{
- Write-Host "`t Windows 10/ Server 2016 not detected. Exiting" -ForegroundColor Red
- Write-Host "Press any key to continue ..."
- $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") | OUT-NULL
- $HOST.UI.RawUI.Flushinputbuffer()
- Exit
+ Write-Error "Windows 10/ Server 2016 not detected. Exiting"
+ Exit
}
-# Checking Folder Structure
+Write-Verbose -Message "Checking Folder Structure"
'OSClient','OSServer','Tools\DSC','Tools\ToolsVHD\DiskSpd','OSServer\Packages','OSClient\Packages' | ForEach-Object {
if (!( Test-Path "$Workdir\$_" )) { New-Item -Type Directory -Path "$workdir\$_" } }
@@ -52,72 +48,73 @@ If (!( Test-Path -Path "$workdir\OSServer\Packages\Copy_MSU_or_Cab_packages_here
If (!( Test-Path -Path "$workdir\OSClient\Packages\Copy_MSU_or_Cab_packages_here.txt" )) {
New-Item -Path "$workdir\OSClient\Packages\" -Name Copy_MSU_or_Cab_packages_here.txt -ItemType File }
-# Downloading diskspd if its not in tools folder
+Write-Verbose -Message "Downloading diskspd if its not in tools folder"
Switch ( Test-Path -Path "$workdir\Tools\ToolsVHD\DiskSpd\diskspd.exe" ) {
$false {
- Write-Host "Downloading diskspd" -ForegroundColor Cyan
+ Write-Information -MessageData "Downloading diskspd" -InformationAction Continue
+ try{
+ $webcontent = Invoke-WebRequest -Uri aka.ms/diskspd
+ $downloadurl = $webcontent.BaseResponse.ResponseUri.AbsoluteUri.Substring(0,$webcontent.BaseResponse.ResponseUri.AbsoluteUri.LastIndexOf('/'))+($webcontent.Links | where-object { $_.'data-url' -match '/Diskspd.*zip$' }|Select-Object -ExpandProperty "data-url")
+ Invoke-WebRequest -Uri $downloadurl -OutFile "$workdir\Tools\ToolsVHD\DiskSpd\diskspd.zip"
+ }catch{
+ Write-Error -Message "Failed to download diskspd!"
+ }
+ Write-Verbose -Message "Unnzipping and extracting just diskspd.exe x64"
+ Expand-Archive "$workdir\Tools\ToolsVHD\DiskSpd\diskspd.zip" -DestinationPath "$workdir\Tools\ToolsVHD\DiskSpd\Unzip"
+ Copy-Item -Path (Get-ChildItem -Path "$workdir\tools\toolsvhd\diskspd\" -Recurse | Where-Object {$_.Directory -like '*amd64fre*' -and $_.name -eq 'diskspd.exe' }).fullname -Destination "$workdir\Tools\ToolsVHD\DiskSpd\"
+ Remove-Item -Path "$workdir\Tools\ToolsVHD\DiskSpd\diskspd.zip"
+ Remove-Item -Path "$workdir\Tools\ToolsVHD\DiskSpd\Unzip" -Recurse -Force
- $webcontent = Invoke-WebRequest -Uri aka.ms/diskspd
- $downloadurl = $webcontent.BaseResponse.ResponseUri.AbsoluteUri.Substring(0,$webcontent.BaseResponse.ResponseUri.AbsoluteUri.LastIndexOf('/'))+($webcontent.Links | where-object { $_.'data-url' -match '/Diskspd.*zip$' }|Select-Object -ExpandProperty "data-url")
- Invoke-WebRequest -Uri $downloadurl -OutFile "$workdir\Tools\ToolsVHD\DiskSpd\diskspd.zip"
- # Unnzipping and extracting just diskspd.exe x64
- Expand-Archive "$workdir\Tools\ToolsVHD\DiskSpd\diskspd.zip" -DestinationPath "$workdir\Tools\ToolsVHD\DiskSpd\Unzip"
- Copy-Item -Path (Get-ChildItem -Path "$workdir\tools\toolsvhd\diskspd\" -Recurse | Where-Object {$_.Directory -like '*amd64fre*' -and $_.name -eq 'diskspd.exe' }).fullname -Destination "$workdir\Tools\ToolsVHD\DiskSpd\"
- Remove-Item -Path "$workdir\Tools\ToolsVHD\DiskSpd\diskspd.zip"
- Remove-Item -Path "$workdir\Tools\ToolsVHD\DiskSpd\Unzip" -Recurse -Force
}
}
-# Download convert-windowsimage if its not in tools folder
+Write-Verbose -Message "Download convert-windowsimage if its not in tools folder"
Switch ( Test-Path -Path "$workdir\Tools\convert-windowsimage.ps1" ) {
$false {
- Write-Host "Downloading Convert-WindowsImage" -ForegroundColor Cyan
- Invoke-WebRequest -Uri https://raw.githubusercontent.com/Microsoft/Virtualization-Documentation/master/hyperv-tools/Convert-WindowsImage/Convert-WindowsImage.ps1 -OutFile "$workdir\Tools\convert-windowsimage.ps1"
+ Write-Information -MessageData "Downloading Convert-WindowsImage" -InformationAction Continue
+ try {
+ Invoke-WebRequest -Uri https://raw.githubusercontent.com/Microsoft/Virtualization-Documentation/master/hyperv-tools/Convert-WindowsImage/Convert-WindowsImage.ps1 -OutFile "$workdir\Tools\convert-windowsimage.ps1"
+ }
+ catch {
+ Write-Error -Message "Failed to download Convert-WindowsImage!"
+ }
}
}
-# Specify needed modules and required version
+Write-Verbose -Message "Specify needed modules and required version"
$modules=("xActiveDirectory","2.10.0.0"),("xDHCpServer","1.3.0.0"),("xNetworking","2.8.0.0"),("xPSDesiredStateConfiguration","3.9.0.0")
-# Downloading modules into Tools folder if needed.
+Write-Verbose -Message "Downloading modules into Tools folder if needed."
foreach ($module in $modules){
- #testing if modules are present
- Write-Host "Testing if modules are present" -ForegroundColor Cyan
+ Write-Verbose -Message "Testing if modules are present"
$modulename=$module[0]
$moduleversion=$module[1]
if (!(Test-Path $workdir'\Tools\DSC\'$modulename'\')){
- Write-Host "Module $module not found... Downloading"
- ### Install NuGET package provider ###
- if ((Get-PackageProvider -Name NuGet) -eq $null){
+ Write-Information -MessageData "Module $module not found... Downloading"
+ if ((Get-PackageProvider -Name NuGet) -eq $null){
+ Write-Verbose -Message "Install NuGET package provider"
Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force
}
Find-DscResource -moduleName $modulename -RequiredVersion $moduleversion | Save-Module -Path $workdir'\Tools\DSC'
}else{
- Write-Host "Module $modulename version found... Skipping Download"
+ Write-Information -MessageData "Module $modulename version found... Skipping Download" -InformationAction Continue
}
}
-# Installing modules if needed
+Write-Verbose -Message "Installing modules if needed"
foreach ($module in $modules) {
- Write-Host "Testing DSC Module $module Presence" -ForegroundColor Cyan
- # Check if Module is installed
+ Write-Information -MessageData "Testing DSC Module $module Presence"
if ((Get-DscResource -Module $Module[0] | where-object {$_.version -eq $module[1]}) -eq $Null) {
- # module is not installed - install it
- Write-Host "Module $module will be installed"
+ Write-Information -MessageData "Module $module will be installed" -InformationAction Continue
$modulename=$module[0]
$moduleversion=$module[1]
Copy-item -Path "$workdir\Tools\DSC\$modulename" -Destination "C:\Program Files\WindowsPowerShell\Modules" -Recurse -Force
- Write-Host "Module was installed." -ForegroundColor Green
+ Write-Information -MessageData "Module was installed." -InformationAction Continue
Get-DscResource -Module $modulename
- Write-Host ""
} else {
- # module is already installed
- Write-Host "Module $Module is already installed"
- Write-Host ""
+ Write-Information -MessageData "Module $Module is already installed" -InformationAction Continue
}
}
# finishing
-Write-Host "Script finished at $(Get-date) and took $(((get-date) - $StartDateTime).TotalMinutes) Minutes"
-Stop-Transcript
-Write-Host "Press any key to continue..." -ForegroundColor Green
-$host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") | OUT-NULL
\ No newline at end of file
+Write-Information -MessageData "Script finished at $(Get-date) and took $(((get-date) - $StartDateTime).TotalMinutes) Minutes" -InformationAction Continue
+Stop-Transcript
\ No newline at end of file
diff --git a/Scripts/2_CreateParentDisks.ps1 b/Scripts/2_CreateParentDisks.ps1
index d6f79635..1782896f 100644
--- a/Scripts/2_CreateParentDisks.ps1
+++ b/Scripts/2_CreateParentDisks.ps1
@@ -1,234 +1,100 @@
-# Verify Running as Admin
-$isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")
-If (!( $isAdmin )) {
- Write-Host "-- Restarting as Administrator" -ForegroundColor Cyan ; Sleep -Seconds 1
- Start-Process powershell.exe "-NoProfile -ExecutionPolicy Bypass -File `"$PSCommandPath`"" -Verb RunAs
- exit
-}
+#Requires -RunAsAdministrator
+[CmdletBinding()]
+param()
-###Get workdirectory###
-$workdir=Split-Path $script:MyInvocation.MyCommand.Path
+Write-Verbose -Message "Loading Functions"
+. .\functions.ps1
-###Start LOG###
-Start-Transcript -Path $workdir\CreateParentDisks.log
+Write-Verbose -Message "Get workdirectory and Start Time"
+$workdir = Get-ScriptDirectory
+Start-Transcript -Path $workdir\CreateParentDisks.log -Append
$StartDateTime = get-date
-Write-host "Script started at $StartDateTime"
-
-#Temp variables
+Write-Output "Script started at $StartDateTime"
-##Load Variables....
+Write-Verbose -Message "Load Variables Script"
. "$($workdir)\variables.ps1"
-#Variables
-##################################
+#region Variables
$AdminPassword=$LabConfig.AdminPassword
$Switchname='DC_HydrationSwitch'
$VMName='DC'
-##################################
-
-
-#############
-# Functions #
-#############
-
-#Create Unattend for VHD
-Function Create-UnattendFileVHD{
- param (
- [parameter(Mandatory=$true)]
- [string]
- $Computername,
- [parameter(Mandatory=$true)]
- [string]
- $AdminPassword,
- [parameter(Mandatory=$true)]
- [string]
- $Path
- )
+#endregion
- if ( Test-Path "$path\Unattend.xml" ) {
- Remove-Item "$Path\Unattend.xml"
- }
- $unattendFile = New-Item "$Path\Unattend.xml" -type File
- $fileContent = @"
-
-
-
-
-
- 1
-
-
-
-
- $Computername
- PFE
- Contoso
-
-
-
-
-
-
- $AdminPassword
- true
-
-
-
- true
- true
- true
-
-
-
-
-
-"@
-
- Set-Content -path $unattendFile -value $fileContent
-
- #return the file object
- Return $unattendFile
-}
-##############
-# Lets start #
-##############
-#Check if Hyper-V is installed.
-Write-Host "Checking if Hyper-V is installed" -ForegroundColor Cyan
+Write-Information -MessageData "Checking if Hyper-V is installed" -InformationAction Continue
if ((Get-WindowsOptionalFeature -Online -FeatureName Microsoft-Hyper-V).state -eq 'Enabled'){
- Write-Host "`t Hyper-V is Installed" -ForegroundColor Green
+ Write-Verbose -Message "Hyper-V is Installed"
}else{
- Write-Host "`t Hyper-V not installed. Please install hyper-v feature including Hyper-V management tools. Exiting" -ForegroundColor Red
- Write-Host "Press any key to continue ..."
- $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") | OUT-NULL
- $HOST.UI.RawUI.Flushinputbuffer()
+ Write-Error "Hyper-V not installed. Please install hyper-v feature including Hyper-V management tools. Exiting"
Exit
}
-## Test for unpacked media - detect install.wim
+Write-Verbose -Message "Test for unpacked media - detect install.wim"
If (Test-Path -Path "$workdir\OSServer\Sources\install.wim"){
- Write-Host "ISO content found under $workdir\OSServer folder" -ForegroundColor Green
- $ServerMediaPath="$workdir\OSServer"
+ $ServerMediaPath="$workdir\OSServer"
+ Write-Information -MessageData "Server install.wim found under $ServerMediaPath " -InformationAction Continue
}else{
- ## Test for ISO and if no ISO found, open file dialog to select one
- If (Test-Path -Path "$workdir\OSServer"){
- $ISOServer = Get-ChildItem -Path "$workdir\OSServer" -Recurse -Include '*.iso' -ErrorAction SilentlyContinue
- }
-
- if ( -not [bool]($ISOServer)){
- Write-Host "No ISO found in $Workdir\OSServer" -ForegroundColor Green
- Write-Host "please select ISO file with Windows Server 2016 wim file. Please use TP5 and newer" -ForegroundColor Green
-
- [reflection.assembly]::loadwithpartialname(“System.Windows.Forms”)
- $openFile = New-Object System.Windows.Forms.OpenFileDialog
- $openFile.Filter = “iso files (*.iso)|*.iso|All files (*.*)|*.*”
- If($openFile.ShowDialog() -eq “OK”)
- {
- Write-Output "File $openfile.name selected" -ForegroundColor Green
- }
- if (!$openFile.FileName){
- Write-Host "Iso was not selected... Exitting" -ForegroundColor Red
- Write-Host "Press any key to continue ..."
- $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") | OUT-NULL
- $HOST.UI.RawUI.Flushinputbuffer()
- Exit
- }
- $ISOServer = Mount-DiskImage -ImagePath $openFile.FileName -PassThru
- }else {
- Write-Host "Found ISO $($ISOServer.FullName)" -ForegroundColor Green
- $ISOServer = Mount-DiskImage -ImagePath $ISOServer.FullName -PassThru
- }
+ Write-Verbose -Message "Test for Server ISO and mount if found"
+ $ISOServer = Mount-ISO -Path "$workdir\OSServer"
$ServerMediaPath = (Get-Volume -DiskImage $ISOServer).DriveLetter+':'
}
If ($LabConfig.CreateClientParent -eq "Yes"){
If (Test-Path -Path "$workdir\OSClient\Sources\install.wim"){
- Write-Host "ISO content found under $workdir\OSClient folder" -ForegroundColor Green
- $ClientMediaPath="$workdir\OSClient"
+ $ClientMediaPath="$workdir\OSClient"
+ Write-Information -MessageData "Client install.wim found under $ClientMediaPath" -InformationAction Continue
}else{
- ## Test for ISO and if no ISO found, open file dialog to select one
- If (Test-Path -Path "$workdir\OSClient"){
- $ISOClient = Get-ChildItem -Path "$workdir\OSClient" -Recurse -Include '*.iso' -ErrorAction SilentlyContinue
- }
-
- if ( -not [bool]($ISOClient)){
- Write-Host "No ISO found in $Workdir\OSOSClient" -ForegroundColor Green
- Write-Host "please select ISO file with Windows 10 wim file. Please use 10586 and newer" -ForegroundColor Green
-
- [reflection.assembly]::loadwithpartialname(“System.Windows.Forms”)
- $openFile = New-Object System.Windows.Forms.OpenFileDialog
- $openFile.Filter = “iso files (*.iso)|*.iso|All files (*.*)|*.*”
- If($openFile.ShowDialog() -eq “OK”){
- Write-Output "File $openfile.name selected" -ForegroundColor Green
- }
- if (!$openFile.FileName){
- Write-Host "Iso was not selected... Exitting" -ForegroundColor Red
- Write-Host "Press any key to continue ..."
- $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") | OUT-NULL
- $HOST.UI.RawUI.Flushinputbuffer()
- Exit
- }
- $ISOClient = Mount-DiskImage -ImagePath $openFile.FileName -PassThru
- }else {
- Write-Host "Found ISO $($ISOClient.FullName)" -ForegroundColor Green
- $ISOClient = Mount-DiskImage -ImagePath $ISOClient.FullName -PassThru
- }
+ Write-Verbose -Message "Test for Client ISO and mount if found"
+ $ISOClient = Mount-ISO -Path "$workdir\OSClient"
$ClientMediaPath = (Get-Volume -DiskImage $ISOClient).DriveLetter+':'
}
}
-#grab server packages
+Write-Verbose -Message "grab packages"
$ServerPackages=Get-ChildItem "$workdir\OSServer\Packages" -Recurse | where {$_.Extension -eq ".msu" -or $_.Extension -eq ".cab"}
-$ClientPackages=Get-ChildItem "$workdir\OSClient\Packages" -Recurse | where {$_.Extension -eq ".msu" -or $_.Extension -eq ".cab"}
-
if ($ServerPackages -ne $null){
-Write-Host "Server Packages Found" -ForegroundColor Cyan
-$ServerPackages | ForEach-Object {Write-Host $_.Name}
+ Write-Information -MessageData "Server Packages Found" -InformationAction Continue
+ $ServerPackages | ForEach-Object {Write-Information -MessageData $_.Name -InformationAction Continue}
}
+If ($LabConfig.CreateClientParent -eq "Yes"){
+ $ClientPackages=Get-ChildItem "$workdir\OSClient\Packages" -Recurse | where {$_.Extension -eq ".msu" -or $_.Extension -eq ".cab"}
+ if ($ClientPackages -ne $null){
+ Write-Information -MessageData "Client Packages Found" -InformationAction Continue
+ $ClientPackages | ForEach-Object {Write-Information -MessageData $_.Name -InformationAction Continue}
+ }
-if ($ClientPackages -ne $null){
-Write-Host "Client Packages Found" -ForegroundColor Cyan
-$ClientPackages | ForEach-Object {Write-Host $_.Name}
+}
+("ParentDisks","Temp","Temp\mountdir","Temp\packages","Tools\dism")|ForEach-Object{
+ If(!(Test-Path -Path $_)){
+ Write-Verbose -Message "Creating $workdir\$_"
+ New-Item -Type Directory -Path "$workdir\$_"
+ }
}
-New-Item -Type Directory -Path "$workdir\ParentDisks"
-New-Item -Type Directory -Path "$workdir\Temp" -Force
-New-Item -Type Directory -Path "$workdir\Temp\mountdir"
-New-Item -Type Directory -Path "$workdir\Tools\dism"
-New-Item -Type Directory -Path "$workdir\Temp\packages"
. "$workdir\tools\convert-windowsimage.ps1"
+Write-Verbose -Message "Create Server Core Parent disk"
Convert-WindowsImage -SourcePath $ServerMediaPath'\sources\install.wim' -Edition ServerDataCenterCore -VHDPath $workdir'\ParentDisks\Win2016Core_G2.vhdx' -SizeBytes 30GB -VHDFormat VHDX -DiskLayout UEFI
-#Create client OS VHD
If ($LabConfig.CreateClientParent -eq "Yes"){
-Convert-WindowsImage -SourcePath $ClientMediaPath'\sources\install.wim' -Edition $LabConfig.ClientEdition -VHDPath $workdir'\ParentDisks\Win10_G2.vhdx' -SizeBytes 30GB -VHDFormat VHDX -DiskLayout UEFI
+ Write-Verbose -Message "Create Client Parent disk"
+ Convert-WindowsImage -SourcePath $ClientMediaPath'\sources\install.wim' -Edition $LabConfig.ClientEdition -VHDPath $workdir'\ParentDisks\Win10_G2.vhdx' -SizeBytes 30GB -VHDFormat VHDX -DiskLayout UEFI
}
-
-#copy dism tools
-
+Write-Verbose -Message "copy dism tools from Server Image"
Copy-Item -Path $ServerMediaPath'\sources\api*downlevel*.dll' -Destination $workdir\Tools\dism
Copy-Item -Path $ServerMediaPath'\sources\*provider*' -Destination $workdir\Tools\dism
Copy-Item -Path $ServerMediaPath'\sources\*dism*' -Destination $workdir\Tools\dism
Copy-Item -Path $ServerMediaPath'\nanoserver\packages\*' -Destination $workdir\Temp\packages\ -Recurse
-
#Old way
#Todo: use the tool for NanoServer
if (Test-Path -Path $ServerMediaPath'\nanoserver\Packages\en-us\*en-us*'){
#vnext version
+ Write-Verbose -Message "Create Nano Server Parent disk"
Convert-WindowsImage -SourcePath $ServerMediaPath'\Nanoserver\NanoServer.wim' -edition 2 -VHDPath $workdir'\ParentDisks\Win2016Nano_G2.vhdx' -SizeBytes 30GB -VHDFormat VHDX -DiskLayout UEFI
&"$workdir\Tools\dism\dism" /Mount-Image /ImageFile:$workdir\Parentdisks\Win2016Nano_G2.vhdx /Index:1 /MountDir:$workdir\Temp\mountdir
&"$workdir\Tools\dism\dism" /Add-Package /PackagePath:$workdir\Temp\packages\Microsoft-NanoServer-DSC-Package.cab /Image:$workdir\Temp\mountdir
@@ -242,7 +108,8 @@ if (Test-Path -Path $ServerMediaPath'\nanoserver\Packages\en-us\*en-us*'){
&"$workdir\Tools\dism\dism" /Add-Package /PackagePath:$workdir\Temp\packages\Microsoft-NanoServer-SCVMM-Package.cab /Image:$workdir\Temp\mountdir
&"$workdir\Tools\dism\dism" /Add-Package /PackagePath:$workdir\Temp\packages\en-us\Microsoft-NanoServer-SCVMM-Package_en-us.cab /Image:$workdir\Temp\mountdir
&"$workdir\Tools\dism\dism" /Unmount-Image /MountDir:$workdir\Temp\mountdir /Commit
-
+
+ Write-Verbose -Message "Create Nano Server HV Parent disk"
Copy-Item -Path "$workdir\Parentdisks\Win2016Nano_G2.vhdx" -Destination "$workdir\ParentDisks\Win2016NanoHV_G2.vhdx"
&"$workdir\Tools\dism\dism" /Mount-Image /ImageFile:$workdir\Parentdisks\Win2016NanoHV_G2.vhdx /Index:1 /MountDir:$workdir\Temp\mountdir
@@ -252,36 +119,32 @@ if (Test-Path -Path $ServerMediaPath'\nanoserver\Packages\en-us\*en-us*'){
&"$workdir\Tools\dism\dism" /Add-Package /PackagePath:$workdir\Temp\packages\en-us\Microsoft-NanoServer-SCVMM-Compute-Package_en-us.cab /Image:$workdir\Temp\mountdir
&"$workdir\Tools\dism\dism" /Unmount-Image /MountDir:$workdir\Temp\mountdir /Commit
- #do some servicing
- 'Win2016Core_G2.vhdx','Win2016Nano_G2.vhdx','Win2016NanoHV_G2.vhdx' | ForEach-Object {
- &"$workdir\Tools\dism\dism" /Mount-Image /ImageFile:$workdir\Parentdisks\$_ /Index:1 /MountDir:$workdir\Temp\mountdir
- $ServerPackages | ForEach-Object {
- $packagepath=$_.FullName
- &"$workdir\Tools\dism\dism" /Add-Package /PackagePath:$packagepath /Image:$workdir\Temp\mountdir
- }
- &"$workdir\Tools\dism\dism" /Unmount-Image /MountDir:$workdir\Temp\mountdir /Commit
- }
-
- If ($LabConfig.CreateClientParent -eq "Yes"){
- &"$workdir\Tools\dism\dism" /Mount-Image /ImageFile:$workdir\Parentdisks\Win10_G2.vhdx /Index:1 /MountDir:$workdir\Temp\mountdir
- $ClientPackages | ForEach-Object {
- $packagepath=$_.FullName
- &"$workdir\Tools\dism\dism" /Add-Package /PackagePath:$packagepath /Image:$workdir\Temp\mountdir
- }
- &"$workdir\Tools\dism\dism" /Unmount-Image /MountDir:$workdir\Temp\mountdir /Commit
- }
-
}else{
-
- Write-Host "`t Please use Windows Server TP5 and newer. Exiting" -ForegroundColor Red
- Write-Host "Press any key to continue ..."
- $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") | OUT-NULL
- $HOST.UI.RawUI.Flushinputbuffer()
+ Write-Error "Please use Windows Server TP5 and newer. Exiting"
Exit
}
-#create Tools VHDX
+Write-Verbose -Message "do some servicing"
+'Win2016Core_G2.vhdx','Win2016Nano_G2.vhdx','Win2016NanoHV_G2.vhdx' | ForEach-Object {
+ &"$workdir\Tools\dism\dism" /Mount-Image /ImageFile:$workdir\Parentdisks\$_ /Index:1 /MountDir:$workdir\Temp\mountdir
+ $ServerPackages | ForEach-Object {
+ $packagepath=$_.FullName
+ &"$workdir\Tools\dism\dism" /Add-Package /PackagePath:$packagepath /Image:$workdir\Temp\mountdir
+ }
+ &"$workdir\Tools\dism\dism" /Unmount-Image /MountDir:$workdir\Temp\mountdir /Commit
+}
+
+If ($LabConfig.CreateClientParent -eq "Yes"){
+ &"$workdir\Tools\dism\dism" /Mount-Image /ImageFile:$workdir\Parentdisks\Win10_G2.vhdx /Index:1 /MountDir:$workdir\Temp\mountdir
+ $ClientPackages | ForEach-Object {
+ $packagepath=$_.FullName
+ &"$workdir\Tools\dism\dism" /Add-Package /PackagePath:$packagepath /Image:$workdir\Temp\mountdir
+ }
+ &"$workdir\Tools\dism\dism" /Unmount-Image /MountDir:$workdir\Temp\mountdir /Commit
+}
+
+Write-Verbose -Message "create Tools VHDX"
$vhd=New-VHD -Path "$workdir\ParentDisks\tools.vhdx" -SizeBytes 30GB -Dynamic
$VHDMount = Mount-VHD $vhd.Path -Passthru
@@ -296,21 +159,19 @@ if (!$VHDPathTest){
}
if ($VHDPathTest){
- Write-Host "Found $workdir\Tools\ToolsVHD\*, copying files into VHDX"
+ Write-Information -MessageData "Found $workdir\Tools\ToolsVHD\*, copying files into VHDX" -InformationAction Continue
Copy-Item -Path "$workdir\Tools\ToolsVHD\*" -Destination ($vhddiskpart.DriveLetter+':\') -Recurse -Force
}else{
- write-host "Files not found"
- Write-Host "Add required tools into $workdir\Tools\toolsVHD and Press any key to continue..." -ForegroundColor Green
+ Write-Warning -Message "Files not found"
+ Write-Warning -Message "Add required tools into $workdir\Tools\toolsVHD and Press any key to continue..."
$host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") | OUT-NULL
Copy-Item -Path "$workdir\Tools\ToolsVHD\*" -Destination ($vhddiskpart.DriveLetter+':\') -Recurse -Force
}
Dismount-VHD $vhddisk.Number
-##############
-# Hydrate DC #
-##############
+#region Hydrate DC
$workdir
$vhdpath=$workdir+'\LAB\'+$VMName+'\Virtual Hard Disks\'+$VMName+'.vhdx'
$VMPath=$Workdir+'\LAB\'
@@ -648,42 +509,50 @@ Copy-Item -Path "$workdir\Temp\config\dc.meta.mof" -Destination "$workdir\Temp\m
#Start and wait for configuration
-$DC | Start-VM
-
-$VMStartupTime = 250
-Write-host "Configuring DC takes a while"
-Write-host "Initial configuration in progress. Sleeping $VMStartupTime seconds"
-Start-Sleep $VMStartupTime
-
-do{
- $test=Invoke-Command -VMGuid $DC.id -ScriptBlock {Get-DscConfigurationStatus} -Credential $cred -ErrorAction SilentlyContinue
- if ($test -eq $null) {
- Write-Host "Configuration in Progress. Sleeping 10 seconds"
- }else{
- Write-Host "Current DSC state: $($test.status), ResourncesNotInDesiredState: $($test.resourcesNotInDesiredState.count), ResourncesInDesiredState: $($test.resourcesInDesiredState.count). Sleeping 10 seconds"
- Write-Host "Invoking DSC Configuration again"
- Invoke-Command -VMGuid $DC.id -ScriptBlock {Start-DscConfiguration -UseExisting} -Credential $cred
- }
- Start-Sleep 10
-}until ($test.Status -eq 'Success' -and $test.rebootrequested -eq $false)
-$test
-
-Invoke-Command -VMGuid $DC.id -ScriptBlock {redircmp 'OU=Workshop,DC=corp,DC=contoso,DC=com'} -Credential $cred -ErrorAction SilentlyContinue
+try{
+ $DC | Start-VM -ErrorAction Stop
+
+ $VMStartupTime = 250
+ Write-Information -MessageData "Configuring DC takes a while" -InformationAction Continue
+ Write-Information -MessageData "Initial configuration in progress. Sleeping $VMStartupTime seconds" -InformationAction Continue
+ Start-Sleep $VMStartupTime
+
+ do{
+ $test=Invoke-Command -VMGuid $DC.id -ScriptBlock {Get-DscConfigurationStatus} -Credential $cred -ErrorAction SilentlyContinue
+ if ($test -eq $null) {
+ Write-Information -MessageData "Configuration in Progress. Sleeping 10 seconds" -InformationAction Continue
+ }else{
+ Write-Information -MessageData "Current DSC state: $($test.status), ResourncesNotInDesiredState: $($test.resourcesNotInDesiredState.count), ResourncesInDesiredState: $($test.resourcesInDesiredState.count). Sleeping 10 seconds" -InformationAction Continue
+ Write-Information -MessageData "Invoking DSC Configuration again" -InformationAction Continue
+ Invoke-Command -VMGuid $DC.id -ScriptBlock {Start-DscConfiguration -UseExisting} -Credential $cred
+ }
+ Start-Sleep 10
+ }until ($test.Status -eq 'Success' -and $test.rebootrequested -eq $false)
+ $test
-$DC | Get-VMNetworkAdapter | Disconnect-VMNetworkAdapter
-$DC | Stop-VM
+ Invoke-Command -VMGuid $DC.id -ScriptBlock {redircmp 'OU=Workshop,DC=corp,DC=contoso,DC=com'} -Credential $cred -ErrorAction SilentlyContinue
+ $DC | Get-VMNetworkAdapter | Disconnect-VMNetworkAdapter
+ $DC | Stop-VM
+}catch{
+ $VMStartError = $true
+ Write-Warning -Message "Unable to Start VM!! "
+}
+#endregion
-#cleanup
+#region cleanup
-###Backup VM Configuration ###
-Copy-Item -Path "$vmpath\$VMNAME\Virtual Machines\" -Destination "$vmpath\$VMNAME\Virtual Machines_Bak\" -Recurse
+Write-Verbose -Message "Backup VM Configuration"
+If($VMStartError -eq $false){
+ Copy-Item -Path "$vmpath\$VMNAME\Virtual Machines\" -Destination "$vmpath\$VMNAME\Virtual Machines_Bak\" -Recurse
+}
$DC | Remove-VM -Force
Remove-Item -Path "$vmpath\$VMNAME\Virtual Machines\" -Recurse
-Rename-Item -Path "$vmpath\$VMNAME\Virtual Machines_Bak\" -NewName 'Virtual Machines'
-Compress-Archive -Path "$vmpath\$VMNAME\Virtual Machines\" -DestinationPath "$vmpath\$VMNAME\Virtual Machines.zip"
-
-###Cleanup The rest ###
+If($VMStartError -eq $false){
+ Rename-Item -Path "$vmpath\$VMNAME\Virtual Machines_Bak\" -NewName 'Virtual Machines'
+ Compress-Archive -Path "$vmpath\$VMNAME\Virtual Machines\" -DestinationPath "$vmpath\$VMNAME\Virtual Machines.zip"
+}
+Write-Verbose -Message "Cleanup the VMSwitch, temp directory, and Unmount any disk Images"
Remove-VMSwitch -Name $Switchname -Force -ErrorAction SilentlyContinue
if ($ISOServer -ne $Null){
$ISOServer | Dismount-DiskImage
@@ -694,9 +563,6 @@ $ISOClient | Dismount-DiskImage
}
Remove-Item -Path "$workdir\temp" -Force -Recurse
-
-Write-Host "Script finished at $(Get-date) and took $(((get-date) - $StartDateTime).TotalMinutes) Minutes"
-
-Stop-Transcript
-Write-Host "Job Done. Press any key to continue..." -ForegroundColor Green
-$host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown") | OUT-NULL
\ No newline at end of file
+#endregion
+Write-Output "Script finished at $(Get-date) and took $(((get-date) - $StartDateTime).TotalMinutes) Minutes"
+Stop-Transcript
\ No newline at end of file
diff --git a/Scripts/Functions.ps1 b/Scripts/Functions.ps1
new file mode 100644
index 00000000..5d4cfd53
--- /dev/null
+++ b/Scripts/Functions.ps1
@@ -0,0 +1,206 @@
+<#
+Function script to hold all the common fuctions - Longterm this should be a module
+#>
+<#
+.Synopsis
+ Check the supplied path for a single ISO and Mount it. Will display a dialog to prompt for a new path if a ISO is not found in the supplied path.
+.EXAMPLE
+ Mount-ISO -path .\OSSever
+#>
+function Mount-ISO {
+ [CmdletBinding()]
+ param (
+ #Path
+ [parameter(Mandatory=$true)]
+ [string]$Path
+ )
+ Write-Verbose -Message "Test for ISO and if no ISO found, open file dialog to select one"
+ If (Test-Path -Path $Path){
+ $ISO = Get-ChildItem -Path $Path -Recurse -Include '*.iso' -ErrorAction SilentlyContinue
+ }
+
+ if (!($ISO)){
+ Write-Verbose -Message "No ISO found in $Path"
+ [reflection.assembly]::loadwithpartialname("System.Windows.Forms")
+ $openFile = New-Object System.Windows.Forms.OpenFileDialog
+ $openFile.Title = "Select a Windows OS install ISO"
+ $openFile.Filter = "iso files (*.iso)|*.iso|All files (*.*)|*.*"
+ If($openFile.ShowDialog() -eq "OK")
+ {
+ Write-Verbose -Message "File $openfile.name selected"
+ }
+ if (!$openFile.FileName){
+ throw "Iso was not selected... Exiting"
+ }
+ $ISO = Mount-DiskImage -ImagePath $openFile.FileName -PassThru
+ }else {
+ If($ISO.count -eq 1){
+ Write-Verbose -Message "Found ISO $($ISO.FullName)"
+ Mount-DiskImage -ImagePath $ISO.FullName -PassThru
+ }else{
+ throw "There can be only one!! Ensure that there is only one iso file in $Path "
+ }
+ }
+}
+
+<#
+.Synopsis
+ Create a unattened.xml
+.EXAMPLE
+ Create-UnattendFileBlob -Blob $blob.Substring(0,$blob.Length-1) -AdminPassword "NeverUsePasswordAsAPassword"
+#>
+Function Create-UnattendFileVHD{
+ [CmdletBinding()]
+ param (
+ #ComputerName
+ [parameter(Mandatory=$true)]
+ [string]$Computername,
+ #Local Admin Password
+ [parameter(Mandatory=$true)]
+ [string]$AdminPassword,
+ #Path
+ [parameter(Mandatory=$true)]
+ [string]$Path
+ )
+
+ if ( Test-Path "$path\Unattend.xml" ) {
+ Remove-Item "$Path\Unattend.xml"
+ }
+ $unattendFile = New-Item "$Path\Unattend.xml" -type File
+ $fileContent = @"
+
+
+
+
+
+ 1
+
+
+
+
+ $Computername
+ PFE
+ Contoso
+
+
+
+
+
+
+ $AdminPassword
+ true
+
+
+
+ true
+ true
+ true
+
+
+
+
+
+"@
+
+ Set-Content -path $unattendFile -value $fileContent
+
+ #return the file object
+ Return $unattendFile
+}
+
+<#
+.Synopsis
+ Create a unattened.xml with domain join Blob
+.EXAMPLE
+ Create-UnattendFileBlob -Blob $blob.Substring(0,$blob.Length-1) -AdminPassword "NeverUsePasswordAsAPassword"
+#>
+Function Create-UnattendFileBlob{
+ [CmdletBinding()]
+ param(
+ #Domain join Blob
+ [parameter(Mandatory=$true)]
+ [string]$Blob,
+ #Local Admin Password
+ [parameter(Mandatory=$true)]
+ [string]$AdminPassword,
+ #Path to create Unattend.xml
+ [parameter()]
+ [string]$Path="Unattend.xml"
+ )
+
+ if(Test-Path -Path $Path){remove-item -Path $Path}
+ $unattendFile = New-Item -Path $path -type File
+ $fileContent = @"
+
+
+
+
+
+
+
+ $Blob
+
+
+
+
+
+
+
+
+
+ $AdminPassword
+ true
+
+
+ Pacific Standard Time
+
+
+
+
+
+ PFE
+ Contoso
+
+
+
+
+"@
+
+ Set-Content -Path $unattendFile -Value $fileContent
+
+ #return the file object
+ $unattendFile|Write-Output
+}
+
+<#
+.Synopsis
+ returns current Script Directory
+.EXAMPLE
+ Get-ScriptDirectory
+#>
+Function Get-ScriptDirectory{
+ [CmdletBinding()]
+ param()
+ Split-Path -Path $script:MyInvocation.MyCommand.Path|Write-Output
+}
+
+<#
+.Synopsis
+ returns Windows Build Number
+.EXAMPLE
+ Get-ScriptDirectory
+#>
+function Get-WindowsBuildNumber {
+ [CmdletBinding()]
+ param()
+ $os = Get-CimInstance -ClassName Win32_OperatingSystem
+ [int]($os.BuildNumber)|Write-Output
+}
\ No newline at end of file