Addition of functions and simplification

This commit is contained in:
Troy Ault 2016-12-12 13:26:47 -05:00
Родитель 5c2680d030
Коммит e1229178e6
24 изменённых файлов: 1052 добавлений и 731 удалений

Просмотреть файл

@ -47,6 +47,7 @@ Provide a central repository to store configurations and credentials, to allow e
##Updates
* New Utility added [LabInaBox](https://github.com/Microsoft/DSC-data-driven-deployment/tree/dev/utility/LabInaBox)
* LabInaBox updated with new simplified approach. Functions provided which take JSON file with required paramaters.
## Contribute
There are many ways to contribute.

Двоичные данные
utility/LabInaBox/DSCResources/DCResources.zip

Двоичный файл не отображается.

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1,354 @@
function Get-TargetResource
{
[CmdletBinding()]
[OutputType([System.Collections.Hashtable])]
param
(
[parameter(Mandatory = $true)]
[System.String]
$Name,
[parameter(Mandatory = $true)]
[System.String]
$Path
)
$smbShare = Get-SmbShare -Name $Name -ErrorAction SilentlyContinue
$changeAccess = @()
$readAccess = @()
$fullAccess = @()
$noAccess = @()
if ($smbShare -ne $null)
{
$smbShareAccess = Get-SmbShareAccess -Name $Name
$smbShareAccess | % {
$access = $_;
if ($access.AccessRight -eq 'Change' -and $access.AccessControlType -eq 'Allow')
{
$changeAccess += $access.AccountName
}
elseif ($access.AccessRight -eq 'Read' -and $access.AccessControlType -eq 'Allow')
{
$readAccess += $access.AccountName
}
elseif ($access.AccessRight -eq 'Full' -and $access.AccessControlType -eq 'Allow')
{
$fullAccess += $access.AccountName
}
elseif ($access.AccessRight -eq 'Full' -and $access.AccessControlType -eq 'Deny')
{
$noAccess += $access.AccountName
}
}
}
else
{
Write-Verbose "Share with name $Name does not exist"
}
$returnValue = @{
Name = $smbShare.Name
Path = $smbShare.Path
Description = $smbShare.Description
ConcurrentUserLimit = $smbShare.ConcurrentUserLimit
EncryptData = $smbShare.EncryptData
FolderEnumerationMode = $smbShare.FolderEnumerationMode
ShareState = $smbShare.ShareState
ShareType = $smbShare.ShareType
ShadowCopy = $smbShare.ShadowCopy
Special = $smbShare.Special
ChangeAccess = $changeAccess
ReadAccess = $readAccess
FullAccess = $fullAccess
NoAccess = $noAccess
Ensure = if($smbShare) {"Present"} else {"Absent"}
}
$returnValue
}
function Set-AccessPermission
{
[CmdletBinding()]
Param
(
$ShareName,
[string[]]
$UserName,
[string]
[ValidateSet("Change","Full","Read","No")]
$AccessPermission
)
$formattedString = '{0}{1}' -f $AccessPermission,"Access"
Write-Verbose -Message "Setting $formattedString for $UserName"
if ($AccessPermission -eq "Change" -or $AccessPermission -eq "Read" -or $AccessPermission -eq "Full")
{
Grant-SmbShareAccess -Name $Name -AccountName $UserName -AccessRight $AccessPermission -Force
}
else
{
Block-SmbShareAccess -Name $Name -AccountName $userName -Force
}
}
function Remove-AccessPermission
{
[CmdletBinding()]
Param
(
$ShareName,
[string[]]
$UserName,
[string]
[ValidateSet("Change","Full","Read","No")]
$AccessPermission
)
$formattedString = '{0}{1}' -f $AccessPermission,"Access"
Write-Debug -Message "Removing $formattedString for $UserName"
if ($AccessPermission -eq "Change" -or $AccessPermission -eq "Read" -or $AccessPermission -eq "Full")
{
Revoke-SmbShareAccess -Name $Name -AccountName $UserName -Force
}
else
{
UnBlock-SmbShareAccess -Name $Name -AccountName $userName -Force
}
}
function Set-TargetResource
{
[CmdletBinding()]
param
(
[parameter(Mandatory = $true)]
[System.String]
$Name,
[parameter(Mandatory = $true)]
[System.String]
$Path,
[System.String]
$Description,
[System.String[]]
$ChangeAccess,
[System.UInt32]
$ConcurrentUserLimit,
[System.Boolean]
$EncryptData,
[ValidateSet("AccessBased","Unrestricted")]
[System.String]
$FolderEnumerationMode,
[System.String[]]
$FullAccess,
[System.String[]]
$NoAccess,
[System.String[]]
$ReadAccess,
[ValidateSet("Present","Absent")]
[System.String]
$Ensure = 'Present'
)
$psboundparameters.Remove("Debug")
$shareExists = $false
$smbShare = Get-SmbShare -Name $Name -ErrorAction SilentlyContinue
if($smbShare -ne $null)
{
Write-Verbose -Message "Share with name $Name exists"
$shareExists = $true
}
if ($Ensure -eq "Present")
{
if ($shareExists -eq $false)
{
$psboundparameters.Remove("Ensure")
Write-Verbose "Creating share $Name to ensure it is Present"
New-SmbShare @psboundparameters
}
else
{
# Need to call either Set-SmbShare or *ShareAccess cmdlets
if ($psboundparameters.ContainsKey("ChangeAccess"))
{
$changeAccessValue = $psboundparameters["ChangeAccess"]
$psboundparameters.Remove("ChangeAccess")
}
if ($psboundparameters.ContainsKey("ReadAccess"))
{
$readAccessValue = $psboundparameters["ReadAccess"]
$psboundparameters.Remove("ReadAccess")
}
if ($psboundparameters.ContainsKey("FullAccess"))
{
$fullAccessValue = $psboundparameters["FullAccess"]
$psboundparameters.Remove("FullAccess")
}
if ($psboundparameters.ContainsKey("NoAccess"))
{
$noAccessValue = $psboundparameters["NoAccess"]
$psboundparameters.Remove("NoAccess")
}
# Use Set-SmbShare for performing operations other than changing access
$psboundparameters.Remove("Ensure")
$psboundparameters.Remove("Path")
Set-SmbShare @PSBoundParameters -Force
# Use *SmbShareAccess cmdlets to change access
$smbshareAccessValues = Get-SmbShareAccess -Name $Name
if ($ChangeAccess -ne $null)
{
# Blow off whatever is in there and replace it with this list
$smbshareAccessValues | ? {$_.AccessControlType -eq 'Allow' -and $_.AccessRight -eq 'Change'} `
| % {
Remove-AccessPermission -ShareName $Name -UserName $_.AccountName -AccessPermission Change
}
$changeAccessValue | % {
Set-AccessPermission -ShareName $Name -AccessPermission "Change" -Username $_
}
}
$smbshareAccessValues = Get-SmbShareAccess -Name $Name
if ($ReadAccess -ne $null)
{
# Blow off whatever is in there and replace it with this list
$smbshareAccessValues | ? {$_.AccessControlType -eq 'Allow' -and $_.AccessRight -eq 'Read'} `
| % {
Remove-AccessPermission -ShareName $Name -UserName $_.AccountName -AccessPermission Read
}
$readAccessValue | % {
Set-AccessPermission -ShareName $Name -AccessPermission "Read" -Username $_
}
}
$smbshareAccessValues = Get-SmbShareAccess -Name $Name
if ($FullAccess -ne $null)
{
# Blow off whatever is in there and replace it with this list
$smbshareAccessValues | ? {$_.AccessControlType -eq 'Allow' -and $_.AccessRight -eq 'Full'} `
| % {
Remove-AccessPermission -ShareName $Name -UserName $_.AccountName -AccessPermission Full
}
$fullAccessValue | % {
Set-AccessPermission -ShareName $Name -AccessPermission "Full" -Username $_
}
}
$smbshareAccessValues = Get-SmbShareAccess -Name $Name
if ($NoAccess -ne $null)
{
# Blow off whatever is in there and replace it with this list
$smbshareAccessValues | ? {$_.AccessControlType -eq 'Deny'} `
| % {
Remove-AccessPermission -ShareName $Name -UserName $_.AccountName -AccessPermission No
}
$noAccessValue | % {
Set-AccessPermission -ShareName $Name -AccessPermission "No" -Username $_
}
}
}
}
else
{
Write-Verbose "Removing share $Name to ensure it is Absent"
Remove-SmbShare -name $Name -Force
}
}
function Test-TargetResource
{
[CmdletBinding()]
[OutputType([System.Boolean])]
param
(
[parameter(Mandatory = $true)]
[System.String]
$Name,
[parameter(Mandatory = $true)]
[System.String]
$Path,
[System.String]
$Description,
[System.String[]]
$ChangeAccess,
[System.UInt32]
$ConcurrentUserLimit,
[System.Boolean]
$EncryptData,
[ValidateSet("AccessBased","Unrestricted")]
[System.String]
$FolderEnumerationMode,
[System.String[]]
$FullAccess,
[System.String[]]
$NoAccess,
[System.String[]]
$ReadAccess,
[ValidateSet("Present","Absent")]
[System.String]
$Ensure = 'Present'
)
$testResult = $false;
$share = Get-TargetResource -Name $Name -Path $Path -ErrorAction SilentlyContinue -ErrorVariable ev
if ($Ensure -ne "Absent")
{
if ($share.Ensure -eq "Absent")
{
$testResult = $false
}
elseif ($share.Ensure -eq "Present")
{
$Params = 'Name', 'Path', 'Description', 'ChangeAccess', 'ConcurrentUserLimit', 'EncryptData', 'FolderEnumerationMode', 'FullAccess', 'NoAccess', 'ReadAccess', 'Ensure'
if ($PSBoundParameters.Keys.Where({$_ -in $Params}) | ForEach-Object {Compare-Object -ReferenceObject $PSBoundParameters.$_ -DifferenceObject $share.$_})
{
$testResult = $false
}
else
{
$testResult = $true
}
}
}
else
{
if ($share.Ensure -eq "Absent")
{
$testResult = $true
}
else
{
$testResult = $false
}
}
$testResult
}
Export-ModuleMember -Function *-TargetResource

Просмотреть файл

@ -0,0 +1,23 @@
[ClassVersion("1.0.0.0"), FriendlyName("xSmbShare")]
class MSFT_xSmbShare : OMI_BaseResource
{
[Key, Description("Name of the SMB Share")] String Name;
[Required, Description("Path to the share")] String Path;
[Write, Description("Description of the share")] String Description;
[Write, Description("Specifies which user will be granted modify permission to access the share")] String ChangeAccess[];
[Write, Description("Specifies the maximum number of concurrently connected users that the new SMB share may accommodate. If this parameter is set to zero (0), then the number of users is unlimited. The default value is zero (0).")] Uint32 ConcurrentUserLimit;
[Write, Description("Indicates that the share is encrypted.")] Boolean EncryptData;
[Write, Description("Specifies which files and folders in the new SMB share are visible to users."), ValueMap{"AccessBased","Unrestricted"}, Values{"AccessBased","Unrestricted"}] String FolderEnumerationMode;
[Write, Description("Specifies which accounts are granted full permission to access the share.")] String FullAccess[];
[Write, Description("Specifies which accounts are denied access to the share.")] String NoAccess[];
[Write, Description("Specifies which user is granted read permission to access the share.")] String ReadAccess[];
[Write, Description("Specifies if the share should be added or removed"), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure;
[Read, Description("Specfies the state of the share")] String ShareState;
[Read, Description("Specfies the type of the share")] String ShareType;
[Read, Description("Specifies if this share is a ShadowCopy")] String ShadowCopy;
[Read, Description("Specifies if this share is a Special Share. Admin share, default shares, IPC$ share are examples.")] String Special;
};

Просмотреть файл

@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) 2015 Microsoft Corporation.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

Двоичный файл не отображается.

Просмотреть файл

@ -0,0 +1,130 @@
[![Build status](https://ci.appveyor.com/api/projects/status/ttp6jlhjyef83sic/branch/master?svg=true)](https://ci.appveyor.com/project/PowerShell/xsmbshare/branch/master)
# xSmbShare
The **xSmbShare** module contains the **xSmbShare** DSC resource for setting up and configuring an [SMB share](http://technet.microsoft.com/en-us/library/cc734393%28v=WS.10%29.aspx).
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/).
For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.
## Contributing
Please check out common DSC Resources [contributing guidelines](https://github.com/PowerShell/DscResource.Kit/blob/master/CONTRIBUTING.md).
## Resources
### xSmbShare
* **Name**: Name of the SMB share.
* **Path**: Path to the share.
* **Description**: Description of the share.
* **ChangeAccess**: Specifies which user will be granted modify permission to access the share.
* **ConcurrentUserLimit**: Specifies the maximum number of concurrently connected users that the new SMB share may accommodate.
If this parameter is set to 0, then the number of users is unlimited.
The default value is 0.
* **EncryptData**: Indicates that the share is encrypted.
* **FolderEnumerationMode**: Specifies which files and folders in the new SMB share are visible to users.
* **FullAccess**: Specifies which accounts are granted full permission to access the share.
* **NoAccess**: Specifies which accounts are denied access to the share.
* **ReadAccess**: Specifies which accounts are granted read permission to access the share.
* **Ensure**: Specifies if the share should be added or removed.
* **ShareState**: State of the share.
* **ShareType**: Type of the share.
* **ShadowCopy**: Specifies if this share is a ShadowCopy.
* **Special**: Specifies if this share is a Special Share.
Admin shares, default shares, IPC$ share are examples.
## Versions
### Unreleased
### 2.0.0.0
* Converted appveyor.yml to install Pester from PSGallery instead of from Chocolatey.
* Added default value of "Present" for the Ensure parameter. (Note: due to how the module's logic is written, this is a breaking change; DSC configs that did not specify a value for Ensure would have behaved as though it were set to Present in the Test-TargetResource function, but to absent in Set-TargetResource, removing the share instead of creating it.)
### 1.1.0.0
* Fixed bug in xSmbShare resource which was causing Test-TargetResource to return false negatives when more than three parameters were specified.
### 1.0.0.0
* Initial release with the following resources
- xSmbShare
## Examples
#### Ensure the an SMB share exists
This configuration ensures that there is a share with the description of "This is a test SMB Share".
```powershell
Configuration ChangeDescriptionConfig
{
Import-DscResource -Name MSFT_xSmbShare
# A Configuration block can have zero or more Node blocks
Node localhost
{
xSmbShare MySMBShare
{
Ensure = "Present"
Name = "SMBShare1"
Path = "C:\Users\Duser1\Desktop"
Description = "This is a test SMB Share"
}
}
}
ChangeDescriptionConfig
```
### Ensure description and permissions for a share
This configuration ensures that the description and permissions for a share are as specified.
```powershell
Configuration ChangeDescriptionAndPermissionsConfig
{
Import-DscResource -Name MSFT_xSmbShare
# A Configuration block can have zero or more Node blocks
Node localhost
{
# Next, specify one or more resource blocks
xSmbShare MySMBShare
{
Ensure = "Present"
Name = "SMBShare1"
Path = "C:\Users\Duser1\Desktop"
ReadAccess = "User1"
NoAccess = @("User3", "User4")
Description = "This is an updated description for this share"
}
}
}
ChangeDescriptionAndPermissionsConfig
```
### Remove an SMB share
This example ensures that the SMB share used in the previous examples does not exist.
```powershell
Configuration RemoveSmbShareConfig
{
Import-DscResource -Name MSFT_xSmbShare
# A Configuration block can have zero or more Node blocks
Node localhost
{
# Next, specify one or more resource blocks
xSmbShare MySMBShare
{
Ensure = "Absent"
Name = "SMBShare1"
Path = "C:\Users\Duser1\Desktop"
}
}
}
RemoveSmbShareConfig
```

Просмотреть файл

@ -0,0 +1,62 @@
@{
# Version number of this module.
ModuleVersion = '2.0.0.0'
# ID used to uniquely identify this module
GUID = '8831ca9a-3c47-4a5b-b401-29635dd24381'
# Author of this module
Author = 'Microsoft Corporation'
# Company or vendor of this module
CompanyName = 'Microsoft Corporation'
# Copyright statement for this module
Copyright = '(c) 2013 Microsoft Corporation. All rights reserved.'
# Description of the functionality provided by this module
Description = 'Module with DSC Resources for SmbShare area'
# Minimum version of the Windows PowerShell engine required by this module
PowerShellVersion = '4.0'
# Minimum version of the common language runtime (CLR) required by this module
CLRVersion = '4.0'
# Functions to export from this module
FunctionsToExport = '*'
# Cmdlets to export from this module
CmdletsToExport = '*'
# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
PrivateData = @{
PSData = @{
# Tags applied to this module. These help with module discovery in online galleries.
Tags = @('DesiredStateConfiguration', 'DSC', 'DSCResourceKit', 'DSCResource')
# A URL to the license for this module.
LicenseUri = 'https://github.com/PowerShell/xSmbShare/blob/master/LICENSE'
# A URL to the main website for this project.
ProjectUri = 'https://github.com/PowerShell/xSmbShare'
# A URL to an icon representing this module.
# IconUri = ''
# ReleaseNotes of this module
ReleaseNotes = '* Converted appveyor.yml to install Pester from PSGallery instead of from Chocolatey.
* Added default value of "Present" for the Ensure parameter. (Note: due to how the module"s logic is written, this is a breaking change; DSC configs that did not specify a value for Ensure would have behaved as though it were set to Present in the Test-TargetResource function, but to absent in Set-TargetResource, removing the share instead of creating it.)
'
} # End of PSData hashtable
} # End of PrivateData hashtable
}

Просмотреть файл

@ -0,0 +1,22 @@
{
"ScriptLocation": "D:\\LabInaBox\\Scripts",
"DSCResourceDest": "C:\\Program Files\\WindowsPowerShell\\Modules",
"DSCResourceSource":"D:\\LabInaBox\\DSCResources",
"ParentFolderPath": "C:\\LabInaBox\\ParentVMDisks",
"ParentFolderPathSource":"D:\\LabInaBox\\ParentVMDisks",
"ChildFolderPath": "E:\\LabInaBox\\ChildVMDisks\\Demo",
"ISOFolderPath" : "D:\\LabInaBox\\ISO",
"DomainJoinPath": "E:\\LabInaBox\\ChildVMDisks\\Demo\\DomainJoin",
"DCMachineName": "DemoDC",
"DomainJoinServer": ["DemoDSC1","DemoSQL1","DemoSQL2"],
"localAdminPass": "P@ssw0rd",
"domainAdminPass": "P@ssw0rd",
"sysPrepDriveName": "Win16SysPrepFinal.vhdx",
"DCSysPrepDriveName": "Win16SysPrepFinal.vhdx",
"SwitchName": "GuestToGuest210",
"domainname": "DemoLab",
"domainExtention": ".com",
"DomainIpAddress":"192.168.210.1",
"DHCPScopeIpStart": "192.168.210.20",
"DHCPScopeIpEnd":"192.168.210.254"
}

Просмотреть файл

@ -0,0 +1,11 @@
#Requires -RunAsAdministrator
$LabConfig = 'D:\LabInaBox\Examples\DemoConfig.json'
Import-Module -name D:\LabInaBox\modules\LabinaBox.psm1
New-LabinaBox -configuration $LabConfig
Stop-LabinaBox -configuration $LabConfig
Start-LabinaBox -configuration $LabConfig
CheckPoint-LabinaBox -configuration $LabConfig
Remove-LabinaBoxSnapshot -configuration $LabConfig
Remove-LabinaBox -configuration $LabConfig

Просмотреть файл

@ -1,175 +0,0 @@
Param (
[Parameter(Mandatory)][string]$SQLServerBitsLocation,
[Parameter(Mandatory)][string]$DefaultSQLVersion,
[Parameter(Mandatory)][string]$NETLocation,
[Parameter(Mandatory)][pscredential]$InstallerAccount
)
$OutputPath = 'C:\DSC_Mof' #Location where mof files will be stored
$ConfigurationHelperPath = 'C:\DSC-data-driven-deployment\'
$SQLServerBitsLocation = '\\ohdc9000\SQLAutoBuilds'
$DefaultSQLVersion = 'SQL2014'
$NETLocation = '\\ohdc9000\SQLAutoBuilds\SQL2014\WindowsServer2012R2\sources\sxs'
$PSDscAllowDomainUser = $true
$PSDscAllowPlainTextPassword = $true #Should be $false for production workloads
$SQLAdminAccount = $InstallerAccount.UserName
$SQLInstanceName = 'MSSQLSERVER'
$SQLInstallShareDir = 'C:\Program Files\Microsoft SQL Server'
$SQLUserDBDir = 'C:\Program Files\Microsoft SQL Server\Data'
$SQLTempDBLogDir = 'C:\Program Files\Microsoft SQL Server\Data'
$SQLTempDBDir = 'C:\Program Files\Microsoft SQL Server\Data'
$InstallSQLDataDir = 'C:\Program Files\Microsoft SQL ServerL\Data'
$SQLUserDBLogDir = 'C:\Program Files\Microsoft SQL Server\Data'
$InstallSharedWOWDir = 'c:\Program Files (x86)\Microsoft SQL Server'
$Features = 'SQLENGINE,IS,SSMS,ADV_SSMS'
$SQLBackupDir = 'C:\Program Files\Microsoft SQL Server\Backup'
$InstanceDir = 'C:\Program Files\Microsoft SQL Server'
$DMaxDop = $true
$MaxDopVal = '0'
$DMemory = $true
$MinMemory = '256'
$MaxMemory = '512'
$NodetoConfigure = $env:computername
[DSCLocalConfigurationManager()]
Configuration LCM_Push
{
Param(
[string[]]$ComputerName
)
Node $ComputerName
{
Settings
{
AllowModuleOverwrite = $True
ConfigurationMode = 'ApplyAndAutoCorrect'
ActionAfterReboot = 'ContinueConfiguration'
RefreshMode = 'Push'
RebootNodeIfNeeded = $True
}
}
}
LCM_Push -ComputerName localhost -OutputPath $OutputPath
Set-DSCLocalConfigurationManager -cimsession localhost -Path $OutputPath -Verbose -force
Configuration SQLBuild
{
Import-DscResource ModuleName PSDesiredStateConfiguration
Import-DscResource -ModuleName xSQLServer
Node $AllNodes.NodeName
{
# Set LCM to reboot if needed
LocalConfigurationManager
{
AllowModuleOverwrite = $true
RefreshMode = 'Push'
ConfigurationMode = 'ApplyAndAutoCorrect'
RebootNodeIfNeeded = $true
DebugMode = "All"
}
WindowsFeature "NET"
{
Ensure = "Present"
Name = "NET-Framework-Core"
Source = $Node.NETPath
}
WindowsFeature "ADTools"
{
Ensure = "Present"
Name = "RSAT-AD-PowerShell"
Source = $Node.NETPath
}
if($Node.Features)
{
xSqlServerSetup ($Node.NodeName)
{
SourcePath = $Node.SourcePath
SetupCredential = $Node.InstallerServiceAccount
InstanceName = $Node.InstanceName
Features = $Node.Features
SQLSysAdminAccounts = $Node.SQLSysAdminAccounts
InstallSharedDir = $Node.SQLInstallShareDir
InstallSharedWOWDir = $Node.InstallSharedWOWDir
InstanceDir = $Node.InstanceDir
InstallSQLDataDir = $Node.InstallSQLDataDir
SQLUserDBDir = $Node.SQLUserDBDir
SQLUserDBLogDir = $Node.SQLUserDBLogDir
SQLTempDBDir = $Node.SQLTempDBDir
SQLTempDBLogDir = $Node.SQLTempDBLogDir
SQLBackupDir = $Node.SQLBackupDir
DependsOn = '[WindowsFeature]NET'
}
xSqlServerFirewall ($Node.NodeName)
{
SourcePath = $Node.SourcePath
InstanceName = $Node.InstanceName
Features = $Node.Features
DependsOn = ("[xSqlServerSetup]" + $Node.NodeName)
}
xSQLServerPowerPlan ($Node.NodeName)
{
Ensure = "Present"
}
xSQLServerMemory ($Node.NodeName)
{
Ensure = "Present"
SQLInstanceName = $Node.InstanceName
DynamicAlloc = $True
DependsOn = ("[xSqlServerSetup]" + $Node.NodeName)
}
xSQLServerMaxDop($Node.NodeName)
{
Ensure = "Present"
SQLInstanceName = $SQLInstanceName
DynamicAlloc = $true
DependsOn = ("[xSqlServerSetup]" + $Node.NodeName)
}
}
}
}
$ConfigurationData = @{
AllNodes = @(
@{
NodeName = "*"
PSDscAllowPlainTextPassword = $PSDscAllowPlainTextPassword
PSDscAllowDomainUser = $PSDscAllowDomainUser
NETPath = $NETLocation
SourcePath = $("$SQLServerBitsLocation\$DefaultSQLVersion")
InstallerServiceAccount = $InstallerAccount
}
@{
NodeName = $NodetoConfigure
InstanceName = $SQLInstanceName
Features = $Features
SQLSysAdminAccounts = $SQLAdminAccount
InstallSharedDir = $SQLInstallShareDir
InstallSharedWOWDir = $InstallSharedWOWDir
InstanceDir = $SQLInstallShareDir
InstallSQLDataDir = $SQLd
SQLUserDBDir = $SQLUserDBDir
SQLUserDBLogDir = $SQLUserDBLogDir
SQLTempDBDir = $SQLTempDBDir
SQLTempDBLogDir = $SQLTempDBLogDir
SQLBackupDir = $SQLBackupDir
}
)
}
SQLBuild -ConfigurationData $ConfigurationData -OutputPath $OutputPath
Start-DscConfiguration -ComputerName $NodetoConfigure -Path $OutputPath -Verbose -Wait -Force
Set-DscLocalConfigurationManager -Path $OutputPath -Verbose
Start-DscConfiguration -Path $OutputPath -Verbose -Wait -Force

Просмотреть файл

@ -1,67 +0,0 @@
 param (
[Parameter(Mandatory)]
[string]$VMName,
[Parameter(Mandatory)]
[string]$ChildFolderPath,
[Parameter(Mandatory)]
[string]$ParentFolderPath,
[Parameter(Mandatory)]
[string]$sysPrepDriveName,
[Parameter(Mandatory)]
[string]$VMSwitchName
)
Configuration HyperV_CreateVM {
param (
[Parameter(Mandatory)]
[string]$VMName,
[Parameter(Mandatory)]
[string]$ChildFolderPath,
[Parameter(Mandatory)]
[string]$ParentDisk,
[Parameter(Mandatory)]
[string]$VMSwitchName
)
Import-DscResource ModuleName PSDesiredStateConfiguration
Import-DscResource -ModuleName xHyper-V -ModuleVersion 3.5.0.0
Import-DscResource -ModuleName xComputerManagement -ModuleVersion 1.8.0.0
xVMSwitch switch {
Name = $VMSwitchName
Ensure = 'Present'
Type = 'Private'
}
xVHD DiffVHD {
Ensure = 'Present'
Name = $VMName
Path = $ChildFolderPath
ParentPath = $ParentDisk
Generation = 'vhdx'
}
xVMHyperV CreateVM {
Name = $VMName
SwitchName = $VMSwitchName
VhdPath = Join-Path -Path $ChildFolderPath -ChildPath "\$VMName.vhdx"
Path = $ChildFolderPath
ProcessorCount = 2
MaximumMemory = 4GB
MinimumMemory =1GB
RestartIfNeeded = $true
DependsOn = '[xVHD]DiffVHD'
State = 'Running'
Generation = 2
}
}
HyperV_CreateVM -VMName $VMName -ChildFolderPath $ChildFolderPath -ParentDisk "$ParentFolderPath\$sysPrepDriveName" -VMSwitchName $SwitchName -OutputPath $ParentFolderPath
Start-DscConfiguration -Wait -Path $ParentFolderPath -Verbose -Force

Просмотреть файл

@ -1,70 +0,0 @@
 param (
[Parameter(Mandatory)]
[string]$ParentFolderPathSource,
[Parameter(Mandatory)]
[string]$ParentFolderPath,
[Parameter(Mandatory)]
[string]$DSCResourceSource,
[Parameter(Mandatory)]
[string]$DSCResourceDest
)
#Ensure all the Directories and Resources required to configure the Host are present
Configuration ResourceSetup {
param (
[Parameter(Mandatory)]
[string]$ParentFolderPathSource,
[Parameter(Mandatory)]
[string]$ParentFolderPath,
[Parameter(Mandatory)]
[string]$DSCResourceSource,
[Parameter(Mandatory)]
[string]$DSCResourceDest
)
Import-DscResource ModuleName PSDesiredStateConfiguration
File DSCResources
{
Type = "Directory"
Ensure = "Present"
Recurse = $true
Checksum = "modifiedDate"
SourcePath = $DSCResourceSource
DestinationPath = $DSCResourceDest
MatchSource = $true
}
File ParentFolder
{
Type = 'Directory'
Ensure = 'Present'
Recurse = $true
Checksum = "modifiedDate"
SourcePath = $ParentFolderPathSource
DestinationPath = $ParentFolderPath
Force = $true
}
File ChildFolder
{
Type = 'Directory'
Ensure = 'Present'
DestinationPath = $ChildFolderPath
Force = $true
DependsOn = '[File]ParentFolder'
}
File DomainJoin
{
Type = 'Directory'
Ensure = 'Present'
DestinationPath = $DomainJoinPath
Force = $true
DependsOn = '[File]ParentFolder'
}
}
ResourceSetup -ParentFolderPathSource $ParentFolderPathSource -ParentFolderPath $ParentFolderPath -DSCResourceSource $DSCResourceSource -DSCResourceDest $DSCResourceDest -OutputPath $ParentFolderPath
Start-DscConfiguration -Wait -Path $ParentFolderPath -Verbose -Force

Просмотреть файл

@ -1,221 +0,0 @@
#Function to create our Credentials to be passed in plain text for simplicity.
#Do not leverage this for production use
function New-Cred
{
[CmdletBinding()]
Param(
[Parameter(Mandatory = $true, Position = 0)]
[string] $userPass,
[Parameter(Position = 1)]
[string] $userName
)
$password = ConvertTo-SecureString $userPass -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential($userName,$password)
return $cred
}
function WaitForPSDirect
{
[CmdletBinding()]
Param([string]$VMName, $cred)
Write-Output "[$($VMName)]:: Waiting for PowerShell Direct (using $($cred.username))"
while ((Invoke-Command -VMName $VMName -Credential $cred {"Test"} -ea SilentlyContinue) -ne "Test") {Start-Sleep -Seconds 1}}
function WaitForDHCPPSDirect
{
[CmdletBinding()]
Param([string]$VMName, $cred)
Write-Output "[$($VMName)]:: Waiting for DHCP (using $($cred.username))"
Invoke-Command -VMName $VMName -Credential $cred {while ((Get-NetIPAddress | ? AddressFamily -eq IPv4 | ? IPAddress -ne 127.0.0.1).SuffixOrigin -ne "Dhcp") {Start-Sleep -seconds 10} }
}
function New-VMsession
{
[CmdletBinding()]
Param(
[Parameter(Mandatory = $true, Position = 0)]
[string] $MachineName,
[Parameter(Position = 1)]
[PScredential] $Cred
)
$SleepTimer = 5
do {
$s = New-PSSession -VMName $MachineName -Credential $Cred -ErrorAction Ignore
If(!$s){Start-Sleep -Seconds $SleepTimer
Write-Verbose "Waiting to get pssession to $MachineName on $MachineIP sleeping for $SleepTimer sec"}
$SleepTimer = [math]::floor(($SleepTimer *3)/2)
}
until($s)
Return $s
}
function Complete-HostConfig
{
[CmdletBinding()]
Param(
[Parameter(Mandatory = $true)]
[string] $ScriptLocation,
[Parameter(Mandatory = $true)]
[String] $ParentFolderPathSource,
[Parameter(Mandatory = $true)]
[String] $ParentFolderPath,
[Parameter(Mandatory = $true)]
[String] $DSCResourceSource,
[Parameter(Mandatory = $true)]
[String] $DSCResourceDest
)
$HostConfig = @{
ParentFolderPathSource = $ParentFolderPathSource
ParentFolderPath = $ParentFolderPath
DSCResourceSource =$DSCResourceSource
DSCResourceDest = $DSCResourceDest
}
.$(Join-Path -Path $ScriptLocation -ChildPath 'Configuration\LabHostResourcesConfig.ps1') @HostConfig
}
function New-LabVM
{
[CmdletBinding()]
Param(
[Parameter(Mandatory = $true)]
[string] $VMName,
[Parameter(Mandatory = $true)]
[string] $ChildfolderPath,
[Parameter(Mandatory = $true)]
[string] $ParentFolderPath,
[Parameter(Mandatory = $true)]
[string] $sysPrepDriveName,
[Parameter(Mandatory = $true)]
[string] $VmswitchName
)
$LabVmConfig = @{
VMName = $VMName
ChildfolderPath = $ChildFolderPath
ParentFolderPath = $ParentFolderPath
sysPrepDriveName = $sysPrepDriveName
VmswitchName = $SwitchName
}
.$(Join-Path -Path $ScriptLocation -ChildPath 'Configuration\LabHostCreateVMConfig.ps1') @LabVmConfig
}
function Add-LabVMtoDomain
{
[CmdletBinding()]
Param(
[Parameter(Mandatory = $true)]
[string] $DCMachineName,
[Parameter(Mandatory = $true)]
[string] $VMName,
[Parameter(Mandatory = $true)]
[String] $domainname,
[Parameter(Mandatory = $true)]
[String] $Domainnamespace,
[Parameter(Mandatory = $true)]
[pscredential] $localAdminCred,
[Parameter(Mandatory = $true)]
[pscredential] $DomCred,
[Parameter(Mandatory = $true)]
[String] $DomainJoinPath,
[Parameter(Mandatory = $true)]
[String]$DSCResourceSource,
[Parameter(Mandatory = $true)]
[String]$DSCResourceDest = 'C:\Program Files\WindowsPowerShell\Modules',
[Parameter(Mandatory = $true)]
[String]$ScriptLocation
)
$AddtoDomainConfig = @{ MachineName =$VMName
domainname = $domainname
DCMachineName = $DCMachineName
Domainnamespace = $domainnamespace
DSCResourceDest = $DSCResourceDest
DomCred = $DomCred
}
#Wait for DC to finalize DHCP configuration
WaitForDHCPPSDirect -VMName $VMName -cred $localAdminCred
WaitForPSDirect -VMName $DCMachineName -cred $DomCred
Invoke-Command -VMName $DCMachineName -Credential $DomCred -ScriptBlock {djoin /provision /domain $using:domainname /machine $using:VMName /savefile c:\$using:VMName.txt} -ErrorAction Ignore
#Create offline domain join files so we can join Each VM later
$DCSession= New-VMsession -MachineName $DCMachineName -Cred $DomCred
Copy-Item -Path c:\$VMName.txt -Destination $DomainJoinPath -FromSession $DCSession
Remove-PSSession $DCSession -ErrorAction Ignore
#Copy all the DSC resources we will leverage
$ServerSession = New-VMsession -MachineName $VMName -Cred $localAdminCred
Copy-Item -Path "$(Join-Path -Path $DSCResourceSource -ChildPath 'DCResources.zip')" -Destination "$(Join-Path -Path $DSCResourceDest -ChildPath 'DCResources.zip')"-ToSession $ServerSession
Invoke-Command -VMName $VMName -Credential $localAdminCred -ScriptBlock {Expand-Archive -Path "$(Join-Path -Path $args -ChildPath 'DCResources.zip')" -DestinationPath "$args" -Force} -ArgumentList $DSCResourceDest
Copy-Item -Path "$(Join-Path -Path $DSCResourceSource -ChildPath 'CertResources.zip')" -Destination "$(Join-Path -Path $DSCResourceDest -ChildPath 'CertResources.zip')"-ToSession $ServerSession
Invoke-Command -VMName $VMName -Credential $localAdminCred -ScriptBlock {Expand-Archive -Path "$(Join-Path -Path $args -ChildPath 'CertResources.zip')" -DestinationPath "$args" -Force} -ArgumentList $DSCResourceDest
Copy-Item -Path "$(Join-Path -Path $ScriptLocation -ChildPath 'Configuration\LabGuestAddtoDomainDSCConfig.ps1')" -Destination "$(Join-Path -Path $DSCResourceDest -ChildPath 'LabGuestAddtoDomainDSCConfig.ps1')" -ToSession $ServerSession
Copy-Item -Path "$(Join-Path -Path $ScriptLocation -ChildPath 'Configuration\LabGuestPostDomainConfig.ps1')" -Destination "$(Join-Path -Path $DSCResourceDest -ChildPath 'LabGuestPostDomainConfig.ps1')" -ToSession $ServerSession
Copy-Item -Path "$(Join-Path -Path $DomainJoinPath -ChildPath "$VMName.txt")" -Destination "$(Join-Path -Path $DSCResourceDest -ChildPath "$VMName.txt")" -ToSession $ServerSession
#Kick of configuration to Join the Vm to the domain
Invoke-Command -VMName $VMName -Credential $localAdminCred -ScriptBlock {."$(Join-Path -Path $args[4] -ChildPath 'LabGuestAddtoDomainDSCConfig.ps1')" -MachineName $args[0] -domainname $args[1] -DCMachineName $args[2] -domainnamespace $args[3] -DSCResourceDest $args[4] -domainCred $args[5]} -ArgumentList $VMName, $domainname, $DCMachineName,$Domainnamespace,$DSCResourceDest,$DomCred
#Wait for VM to become available then complete the post configuration tasks
WaitForPSDirect -VMName $VMName -cred $DomCred
Invoke-Command -VMName $VMName -Credential $DomCred -ScriptBlock {."$(Join-Path -Path $args[4] -ChildPath 'LabGuestPostDomainConfig.ps1')" -MachineName $args[0] -domainname $args[1] -DCMachineName $args[2] -domainnamespace $args[3] -domainCred $args[5]} -ArgumentList $VMName, $domainname, $DCMachineName,$Domainnamespace,$DSCResourceDest,$DomCred
}
function New-Domain
{
[CmdletBinding()]
Param(
[Parameter(Mandatory = $true)]
[string] $DCMachineName,
[Parameter(Mandatory = $true)]
[String] $domainname,
[Parameter(Mandatory = $true)]
[String] $Domainnamespace,
[Parameter(Mandatory = $true)]
[pscredential] $localAdminCred,
[Parameter(Mandatory = $true)]
[pscredential] $DomCred,
[Parameter(Mandatory = $true)]
[String]$DSCResourceSource,
[Parameter(Mandatory = $true)]
[String]$DSCResourceDest,
[Parameter(Mandatory = $true)]
[String]$ScriptLocation
)
WaitForPSDirect -VMName $DCMachineName -cred $localAdminCred
$DCSession = New-VMsession -MachineName $DCMachineName -Cred $localAdminCred
Copy-Item -Path "$(Join-Path -Path $ScriptLocation -ChildPath 'Configuration\LabGuestPreDomainConfig.ps1')" -Destination "$(Join-Path -Path $DSCResourceDest -ChildPath 'LabGuestPreDomainConfig.ps1')" -ToSession $DCSession
Copy-Item -Path "$(Join-Path -Path $DSCResourceSource -ChildPath 'DCResources.zip')" -Destination "$(Join-Path -Path $DSCResourceDest -ChildPath 'DCResources.zip')"-ToSession $DCSession
Invoke-Command -VMName $DCMachineName -Credential $localAdminCred -ScriptBlock {Expand-Archive -Path "$(Join-Path -Path $args -ChildPath 'DCResources.zip')" -DestinationPath "$args" -Force} -ArgumentList $DSCResourceDest
Invoke-Command -VMName $DCMachineName -Credential $localAdminCred -ScriptBlock {Remove-Item -Path "$(Join-Path -Path $args -ChildPath 'DCResources.zip')" -Force} -ArgumentList $DSCResourceDest
Invoke-Command -VMName $DCMachineName -Credential $localAdminCred -ScriptBlock {."$(Join-Path -Path $args[0] -ChildPath 'LabGuestPreDomainConfig.ps1')" -MachineName $Args[1] -DomainNamespace $Args[2] -DomainIpAddress $Args[3] -DHCPScopeIpStart $Args[4] -DHCPScopeIpEnd $Args[5] -domainCred $Args[6] -safemodeCred $Args[7]} -ArgumentList $DSCResourceDest,$DCMachineName,$domainnamespace,$DomainIpAddress,$DHCPScopeIpStart,$DHCPScopeIpEnd,$DomCred,$localAdminCred
}
function New-DatadrivenDeployment
{
[CmdletBinding()]
Param(
[Parameter(Mandatory = $true)]
[string] $DCMachineName,
[Parameter(Mandatory = $true)]
[String] $MachineName,
[Parameter(Mandatory = $true)]
[pscredential] $localAdminCred,
[Parameter(Mandatory = $true)]
[pscredential] $DomCred,
[Parameter(Mandatory = $true)]
[String]$ScriptLocation
)
$DCSession = New-VMsession -MachineName $DCMachineName -Cred $DomCred
Copy-Item -Path "$ScriptLocation\ISO\*" -Destination "" -ToSession $DCSession
}

Просмотреть файл

@ -1,127 +0,0 @@
# Verify Running as Admin
$isAdmin = ([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")
If (!( $isAdmin )) {
Write-Host "----- Must Run as Admin as Administrator -----" -ForegroundColor Red ;
Write-Host "----- Please re-open ISE as Administrator-----" -ForegroundColor Yellow;
Write-Host "------------------ABORTING!-------------------" -ForegroundColor Red;
BREAK
}
#User will need to rerun the script if HyperV is not configured as a reboot will occur
$start = Get-Date
$start
$ExecutionPolicy = Get-ExecutionPolicy
if ($ExecutionPolicy -eq 'Restricted') {Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force}
######### Required Variables to Configure ########
$ScriptSourceDrive = 'D:\Scripts\LabInaBox'
$ParentDrive = 'C:'
$ChildDrive = 'E:'
$DCMachineName = 'NJDC6000'
$DSCentral = 'NJDSC6000'
[string[]]$DomainJoinServers ='NJSQL6000','NJSQL6001'
$localAdminPass = 'MyFancyP@$$'
$domainAdminPass = 'MyFancyP@$$'
$sysPrepDriveName = 'Win2016Sysprep.vhdx'
$DCSysPrepDriveName = 'Win2016CoreSysPrep.vhdx'
######### Optional Variables to Configure #######################
$SwitchName = 'GuestToGuest'
$DSCResourceSource = Join-Path -Path $ScriptSourceDrive -ChildPath "DSCResources"
$DSCResourceDest = 'C:\Program Files\WindowsPowerShell\Modules'
$ParentFolderPathSource = Join-Path -Path $ScriptSourceDrive -ChildPath 'ParentDisks'
$ParentFolderPath = Join-Path -Path $ParentDrive -ChildPath 'vms\Parent'
$ChildFolderPath = Join-Path -Path $ChildDrive -ChildPath 'vms'
$DomainJoinPath = Join-Path -Path $ChildDrive -ChildPath 'vms\DomainJoin'
$domainname = 'TestLab'
$domainExtention = '.com'
$DomainIpAddress ='192.168.200.1'
$DHCPScopeIpStart = '192.168.200.20'
$DHCPScopeIpEnd ='192.168.200.254'
$domainnamespace = $domainname + $domainExtention
$ScriptLocation = Join-Path -Path $ScriptSourceDrive -ChildPath 'PSScripts'
################################################################
# Loading Helper Functions for HyperVConfig
Import-Module -Name $(Join-Path -Path $ScriptSourceDrive -ChildPath 'PSScripts\LabHostConfigHelper.psm1') -Verbose:$false -ErrorAction Stop
$localAdminCred = New-Cred -userPass $localAdminPass -userName 'administrator'
$DomCred = New-Cred -userPass $domainAdminPass -UserName "$domainname\Administrator"
$MemberServers = $DomainJoinServers + $DSCentral
$AllServers = $MemberServers + $DCMachineName
$HostConfig = @{
ScriptLocation = $ScriptLocation
ParentFolderPathSource = $ParentFolderPathSource
ParentFolderPath = $ParentFolderPath
DSCResourceSource =$DSCResourceSource
DSCResourceDest = $DSCResourceDest
}
$LabVmConfig = @{
ChildfolderPath = $ChildFolderPath
ParentFolderPath = $ParentFolderPath
sysPrepDriveName = $sysPrepDriveName
VmswitchName = $SwitchName
}
$DCVmConfig = @{
ChildfolderPath = $ChildFolderPath
ParentFolderPath = $ParentFolderPath
sysPrepDriveName = $DCSysPrepDriveName
VmswitchName = $SwitchName
VMName = $DCMachineName
}
$DomainConfig = @{
DCMachineName =$DCMachineName
domainname = $domainname
Domainnamespace = $Domainnamespace
localAdminCred = $localAdminCred
DomCred = $DomCred
DSCResourceSource = $DSCResourceSource
DSCResourceDest = $DSCResourceDest
ScriptLocation = $ScriptLocation
}
$AddtoDomainConfig = @{
DCMachineName = $DCMachineName
domainname = $domainname
Domainnamespace = $domainnamespace
localAdminCred = $localAdminCred
DomCred = $DomCred
DomainJoinPath =$DomainJoinPath
DSCResourceSource =$DSCResourceSource
DSCResourceDest = $DSCResourceDest
ScriptLocation = $ScriptLocation
}
#Apply Configuration to the host to ensure we can create Vms
Complete-HostConfig @HostConfig
#Create Domain Vm requested
New-LabVM @DCVmConfig
#Create Each Member Vm requested
$MemberServers | ForEach-Object -Process {New-LabVM @LabVmConfig -VMName $_ -Verbose}
#Apply Domain Controller configuration
New-Domain @DomainConfig -verbose
#Add VMs to domain and run post configuration
$MemberServers | ForEach-Object -Process {Add-LabVMtoDomain @AddtoDomainConfig -VMName $_ -verbose}
$end = Get-Date
$diff = $end -$start
$diff
#Remove lab Vms
<#
$AllServers | ForEach-Object -process {
stop-Vm -name $_ -turnoff
Remove-VM -Name $_ -force
}
Remove-Item $ChildFolderPath -Force -Recurse
#>

Просмотреть файл

@ -1,7 +1,7 @@
[![Build status](https://ci.appveyor.com/api/projects/status/6a59vfritv4kbc7d/branch/master?svg=true)](https://ci.appveyor.com/project/Microsoft/DSC-data-driven-deployment/branch/master)
#Lab In a Box
Utility to allow developers to spin up a sandbox lab environment quickly. Virtual machines will be created on a private network without access to host.
Simple lightweight utility to allow developers to spin up a sandbox lab environment quickly. Virtual machines will be created on a private network without access to host. Ability to create multiple lab environments that can coexist.
#Why
Getting started with DSC can be difficult for developers because they don't have control over all over their environment. Often its difficult to validate secure configurations due to the need for certificates. With LabInaBox these restrictions are lifted since its all encompassed in a sandbox. Active Directory and Certificate services are already installed and configured allowing developers to begin testing their configurations as soon as the deployment is complete.
@ -15,23 +15,34 @@ Getting started with DSC can be difficult for developers because they don't have
##Installation
* Download LabInaBox to a USB drive
* Create folder under LabInaBox named ParentDisks
* Create folder under LabInaBox named ParentVMDisks
* Copy your sysprepped image of Windows 2016 to ParentDisks
* AnswerFile Reference: [https://technet.microsoft.com/en-us/library/cc749317(v=ws.10).aspx](https://technet.microsoft.com/en-us/library/cc749317(v=ws.10).aspx "Building a Simple Answer File")
* Sysprep Command Reference: [https://technet.microsoft.com/en-us/library/hh825033.aspx](https://technet.microsoft.com/en-us/library/hh825033.aspx "Sysprep Command Line")
* Open PowerShell ISE as an administrator
* Open Main_Setup.ps1
* Read through Required Variables to Configure and Optional Variables to Configure
* Open Examples folder
* Modify DemoConfig.json or rename it entirely and modify parameters within
* Ensure you update the ParentFolderPath and ChildFolderPath variables to the drives for your machine
* Modify localAdminPass and domainAdminPass to your liking
* Modify sysPrepDriveName and DCSysPrepDriveName to point to match your name
* I have provided two names here in-case you want to utilize Windows Core for your Domain Controller
* Modify DCMachineName DomainJoinServers variables
* Open Main.ps1 this gives an example of calling each of the functions available
* LabInaBox will utilize your sysprep drive in as a parent differencing disk
* Reference: [https://technet.microsoft.com/en-us/library/cc720381(v=ws.10).aspx](https://technet.microsoft.com/en-us/library/cc720381(v=ws.10).aspx "Using differencing disks")
* For the best performance parent and child disks should be on different disk drives
* Ensure you update the $Parent and $ChildDrive variables to the drives for your machine
* Modify $localAdminPass and $domainAdminPass to your liking
* Modify $sysPrepDriveName and $DCSysPrepDriveName to point to match your name
* I have provided two names here in-case you want to utilize Windows Core for your Domain Controller
* Modify $DCMachineName $DSCentral and $DomainJoinServers variables
* Execute Script
* If Hyper-V is not installed on the machine a reboot will be required and the script will need to be executed one final time.
* If Hyper-V is not installed on the machine a reboot will be required and New-LabinBox will need to be executed again.
*
##Updates
* Simplified approach, functions added which take a JSON file as input with required variables.
* New functions added
* New-LabinaBox
* Stop-LabinaBox
* Start-LabinaBox
* CheckPoint-LabinaBox
* Remote-LabinaBoxSnapshot
* Remove-LabinaBox
##Assumptions
* Requires Windows 10 or Server 2016 as the Host Operating System

Просмотреть файл

@ -1,12 +1,7 @@
Param (
[Parameter(Mandatory)][string]$machineName,
[Parameter(Mandatory)][string]$domainname,
[Parameter(Mandatory)][string]$DCMachineName,
[Parameter(Mandatory)][string]$DSCResourceDest,
[Parameter(Mandatory)][string]$domainnamespace,
[Parameter(Mandatory)][pscredential]$domainCred
[PSCustomObject] $configuration
)
[DSCLocalConfigurationManager()]
Configuration LCM_Push
{
@ -18,7 +13,7 @@ Configuration LCM_Push
Settings
{
AllowModuleOverwrite = $True
ConfigurationMode = 'ApplyAndAutoCorrect'
ConfigurationMode = 'ApplyOnly'
RefreshMode = 'Push'
RebootNodeIfNeeded = $True
}
@ -29,15 +24,10 @@ Set-DSCLocalConfigurationManager -cimsession localhost -Path C:\Mofs -Verbose
configuration AddToDomain
{
param
(
[string[]]$NodeName,
[Parameter(Mandatory)][string]$MachineName,
[Parameter(Mandatory)][string]$domainname,
[Parameter(Mandatory)][string]$DCMachineName,
[Parameter(Mandatory)][string]$DSCResourceDest,
[Parameter(Mandatory)][string]$domainnamespace,
[Parameter(Mandatory)][pscredential]$domainCred
Param (
[Parameter(Mandatory)][string]$nodeName,
[Parameter(Mandatory)][string]$machineName,
[PSCustomObject] $configuration
)
#Import the required DSC Resources
@ -54,7 +44,7 @@ configuration AddToDomain
xOfflineDomainJoin ODJ
{
RequestFile = "$DSCResourceDest\$MachineName.txt"
RequestFile = "$($Configuration.DSCResourceDest)\$MachineName.txt"
IsSingleInstance = 'Yes'
}
}
@ -69,7 +59,7 @@ configuration AddToDomain
}
)
}
AddToDomain -ConfigurationData $cd -NodeName localhost -MachineName $machineName -domainname $domainname -DCMachineName $DCMachineName -DSCResourceDest $DSCResourceDest -domainnamespace $domainnamespace -domainCred $domainCred -OutputPath c:\Mofs
AddToDomain -ConfigurationData $cd -NodeName localhost -MachineName $machineName -configuration $configuration -OutputPath c:\Mofs
Start-DscConfiguration -ComputerName localhost -Path c:\Mofs -Wait -Force -Verbose

Просмотреть файл

@ -1,11 +1,10 @@
Param (
[Parameter(Mandatory)][string]$machineName,
[Parameter(Mandatory)][string]$domainname,
[Parameter(Mandatory)][string]$DCMachineName,
[Parameter(Mandatory)][string]$domainnamespace,
[PSCustomObject] $configuration,
[Parameter(Mandatory)][pscredential]$domainCred
)
[DSCLocalConfigurationManager()]
Configuration LCM_Push
{
@ -17,7 +16,7 @@ Configuration LCM_Push
Settings
{
AllowModuleOverwrite = $True
ConfigurationMode = 'ApplyAndAutoCorrect'
ConfigurationMode = 'ApplyOnly'
RefreshMode = 'Push'
RebootNodeIfNeeded = $True
}
@ -28,13 +27,10 @@ Set-DSCLocalConfigurationManager -cimsession localhost -Path C:\Mofs -Verbose
configuration PostDomainConfig
{
param
(
[string[]]$NodeName,
[Parameter(Mandatory)][string]$MachineName,
[Parameter(Mandatory)][string]$domainname,
[Parameter(Mandatory)][string]$DCMachineName,
[Parameter(Mandatory)][string]$domainnamespace,
Param (
[Parameter(Mandatory)][string]$nodeName,
[Parameter(Mandatory)][string]$machineName,
[PSCustomObject] $configuration,
[Parameter(Mandatory)][pscredential]$domainCred
)
@ -45,9 +41,9 @@ configuration PostDomainConfig
{
xCertReq MyCert
{
CARootName = "$domainname-$DCMachineName-CA"
CAServerFQDN = "$DCMachineName.$domainnamespace"
Subject = "$MachineName.$domainnamespace"
CARootName = "$($Configuration.domainname)-$($Configuration.DCMachineName)-CA"
CAServerFQDN = "$($configuration.domainname)$($configuration.domainExtention)"
Subject = "$MachineName.$($configuration.domainname)$($configuration.domainExtention)"
KeyLength = '1024'
Exportable = $true
ProviderName = '"Microsoft RSA SChannel Cryptographic Provider"'
@ -69,7 +65,7 @@ configuration PostDomainConfig
}
)
}
PostDomainConfig -ConfigurationData $cd -NodeName localhost -MachineName $machineName -domainname $domainname -DCMachineName $DCMachineName -domainnamespace $domainnamespace -domainCred $domainCred -OutputPath c:\Mofs
PostDomainConfig -ConfigurationData $cd -NodeName localhost -MachineName $machineName -configuration $configuration -domainCred $domainCred -OutputPath c:\Mofs
Start-DscConfiguration -ComputerName localhost -Path c:\Mofs -Wait -Force -Verbose

Просмотреть файл

@ -1,9 +1,6 @@
Param (
[Parameter(Mandatory)][string]$machineName,
[Parameter(Mandatory)][string]$DomainNamespace,
[Parameter(Mandatory)][string]$DomainIpAddress,
[Parameter(Mandatory)][string]$DHCPScopeIpStart,
[Parameter(Mandatory)][string]$DHCPScopeIpEnd,
[PSCustomObject] $configuration,
[Parameter(Mandatory)][pscredential]$domainCred,
[Parameter(Mandatory)][pscredential]$safemodeCred
@ -20,7 +17,7 @@ Configuration LCM_Push
Settings
{
AllowModuleOverwrite = $True
ConfigurationMode = 'ApplyAndAutoCorrect'
ConfigurationMode = 'ApplyOnly'
ActionAfterReboot = 'ContinueConfiguration'
RefreshMode = 'Push'
RebootNodeIfNeeded = $True
@ -35,32 +32,29 @@ configuration DomainConfig
param
(
[string[]]$NodeName,
[Parameter(Mandatory)][string]$machineName,
[Parameter(Mandatory)][string]$DomainNamespace,
[Parameter(Mandatory)][string]$DomainIpAddress,
[Parameter(Mandatory)][string]$DHCPScopeIpStart,
[Parameter(Mandatory)][string]$DHCPScopeIpEnd,
[PSCustomObject] $configuration,
[Parameter(Mandatory)][pscredential]$domaincred,
[Parameter(Mandatory)][pscredential]$safemodeCred
)
#Import the required DSC Resources
Import-DscResource ModuleName PSDesiredStateConfiguration
Import-DscResource -ModuleName PSDesiredStateConfiguration
Import-DscResource -ModuleName xComputerManagement -ModuleVersion 1.8.0.0
Import-DscResource -ModuleName xActiveDirectory -ModuleVersion 2.14.0.0
Import-DscResource -ModuleName xNetworking -ModuleVersion 2.12.0.0
Import-DscResource -ModuleName xDhcpServer -ModuleVersion 1.5.0.0
Import-DscResource -ModuleName xADCSDeployment -ModuleVersion 1.0.0.0
Import-DscResource -ModuleName xSmbShare -ModuleVersion 2.0.0.0
Node $NodeName
{
xComputer SetName
{
Name = $machineName
Name = $Configuration.DCMachineName
}
xIPAddress SetIP{
IpAddress = $DomainIpAddress
IpAddress = $Configuration.DomainIpAddress
InterfaceAlias = 'Ethernet'
SubnetMask = '24'
AddressFamily = 'IPv4'
@ -76,12 +70,32 @@ configuration DomainConfig
Name = 'AD-Domain-Services'
}
xADDomain MyDC{
DomainName = $domainnamespace
DomainName = "$($configuration.domainname)$($configuration.domainExtention)"
DomainAdministratorCredential = $domainCred
SafemodeAdministratorPassword = $safemodeCred
DependsOn = '[xComputer]SetName','[xIpAddress]SetIP','[WindowsFeature]ADDSInstall','[WindowsFeature]ADDSTools'
}
if (Test-Path "D:\")
{
xSmbShare SQLShare{
Ensure= 'Present'
Name = 'Source'
Path = 'D:\'
Description = 'SQL Server Installation Media'
}
}
if (Test-Path "E:\")
{
xSmbShare WinShare{
Ensure= 'Present'
Name = 'Windows2016ISO'
Path = 'E:\'
Description = 'Windows Server 2016 Installation Media'
}
}
WindowsFeature ADDSTools
{
Ensure = "Present"
@ -104,8 +118,8 @@ configuration DomainConfig
xDhcpServerScope Scope
{
Ensure = 'Present'
IPStartRange = $DHCPScopeIpStart
IPEndRange = $DHCPScopeIpEnd
IPStartRange = $Configuration.DHCPScopeIpStart
IPEndRange = $Configuration.DHCPScopeIpEnd
Name = 'MyScope'
SubnetMask = '255.255.255.0'
@ -119,11 +133,11 @@ configuration DomainConfig
xDhcpServerOption Option
{
Ensure = 'Present'
ScopeID = $DHCPScopeIpStart
DnsDomain = $DomainNamespace
DnsServerIPAddress = $DomainIpAddress
ScopeID = $Configuration.DHCPScopeIpStart
DnsDomain = "$($configuration.domainname)$($configuration.domainExtention)"
DnsServerIPAddress = $Configuration.DomainIpAddress
AddressFamily = 'IPv4'
Router = $DomainIpAddress
Router = $Configuration.DomainIpAddress
DependsOn = '[xDhcpServerScope]Scope'
}
@ -179,7 +193,7 @@ configuration DomainConfig
}
)
}
DomainConfig -ConfigurationData $cd -NodeName localhost -machineName $machineName -DomainNamespace $DomainNamespace -DomainIpAddress $DomainIpAddress -DHCPScopeIpStart $DHCPScopeIpStart -DHCPScopeIpEnd $DHCPScopeIpEnd -domaincred $domainCred -safemodecred $safemodeCred -OutputPath c:\Mof
DomainConfig -ConfigurationData $cd -NodeName localhost -configuration $configuration -domaincred $domainCred -safemodeCred $safemodeCred -OutputPath c:\Mof
Start-DscConfiguration -ComputerName localhost -Path c:\Mof -Wait -Force -Verbose

Просмотреть файл

@ -0,0 +1,50 @@
param( [Parameter(Mandatory)]
[string]$VMName,
[Parameter(Mandatory)]
[string]$SysPrepImage,
[PSCustomObject]
$configuration
)
Configuration HyperV_CreateVM {
param([Parameter(Mandatory)]
[string]$VMName,
[Parameter(Mandatory)]
[string]$SysPrepImage,
[PSCustomObject]
$configuration
)
Import-DscResource ModuleName PSDesiredStateConfiguration
Import-DscResource -ModuleName xHyper-V -ModuleVersion 3.5.0.0
Import-DscResource -ModuleName xComputerManagement -ModuleVersion 1.8.0.0
xVMSwitch switch {
Name = $configuration.SwitchName
Ensure = 'Present'
Type = 'Private'
}
xVHD DiffVHD {
Ensure = 'Present'
Name = $VMName
Path = $Configuration.ChildFolderPath
ParentPath = "$($Configuration.ParentFolderPath)\$SysPrepImage"
Generation = 'vhdx'
}
xVMHyperV CreateVM {
Name = $VMName
SwitchName = $Configuration.SwitchName
VhdPath = Join-Path -Path $Configuration.ChildFolderPath -ChildPath "\$VMName.vhdx"
Path = $Configuration.ChildFolderPath
ProcessorCount = 2
MaximumMemory = 4GB
MinimumMemory =1GB
RestartIfNeeded = $true
DependsOn = '[xVHD]DiffVHD'
State = 'Running'
Generation = 2
}
}
HyperV_CreateVM -VMName $VMName -Configuration $configuration -SysPrepImage $SysPrepImage -OutputPath C:\Mof
Start-DscConfiguration -Wait -Path C:\Mof -Verbose -Force

Просмотреть файл

@ -9,7 +9,7 @@ Configuration LCM_Push
Settings
{
AllowModuleOverwrite = $True
ConfigurationMode = 'ApplyAndAutoCorrect'
ConfigurationMode = 'ApplyOnly'
ActionAfterReboot = 'ContinueConfiguration'
RefreshMode = 'Push'
RebootNodeIfNeeded = $True

Просмотреть файл

@ -0,0 +1,51 @@
 param( [PSCustomObject]
$configuration
)
#Ensure all the Directories and Resources required to configure the Host are present
Configuration ResourceSetup {
param( [PSCustomObject]
$configuration
)
Import-DscResource ModuleName PSDesiredStateConfiguration
File DSCResources
{
Type = "Directory"
Ensure = "Present"
Recurse = $true
Checksum = "modifiedDate"
SourcePath = $configuration.DSCResourceSource
DestinationPath = $configuration.DSCResourceDest
MatchSource = $true
}
File ParentFolder
{
Type = 'Directory'
Ensure = 'Present'
Recurse = $true
Checksum = "modifiedDate"
SourcePath = $configuration.ParentFolderPathSource
DestinationPath =$configuration.ParentFolderPath
Force = $true
}
File ChildFolder
{
Type = 'Directory'
Ensure = 'Present'
DestinationPath = $configuration.ChildFolderPath
Force = $true
DependsOn = '[File]ParentFolder'
}
File DomainJoin
{
Type = 'Directory'
Ensure = 'Present'
DestinationPath = $configuration.DomainJoinPath
Force = $true
DependsOn = '[File]ParentFolder'
}
}
ResourceSetup -Configuration $configuration -OutputPath $configuration.ParentFolderPath
Start-DscConfiguration -Wait -Path $configuration.ParentFolderPath -Verbose -Force

Просмотреть файл

@ -0,0 +1,245 @@
#Function to create our Credentials to be passed in plain text for simplicity.
#Do not leverage this for production use
function New-Cred
{
[CmdletBinding()]
Param(
[Parameter(Mandatory = $true, Position = 0)]
[string] $userPass,
[Parameter(Position = 1)]
[string] $userName
)
$password = ConvertTo-SecureString $userPass -AsPlainText -Force
$cred = New-Object System.Management.Automation.PSCredential($userName,$password)
return $cred
}
function WaitForPSDirect
{
[CmdletBinding()]
Param([string]$VMName, $cred)
Write-Output "[$($VMName)]:: Waiting for PowerShell Direct (using $($cred.username))"
while ((Invoke-Command -VMName $VMName -Credential $cred {"Test"} -ea SilentlyContinue) -ne "Test") {Start-Sleep -Seconds 1}}
function WaitForDHCPPSDirect
{
[CmdletBinding()]
Param([string]$VMName, $cred)
Write-Output "[$($VMName)]:: Waiting for DHCP (using $($cred.username))"
Invoke-Command -VMName $VMName -Credential $cred {while ((Get-NetIPAddress | ? AddressFamily -eq IPv4 | ? IPAddress -ne 127.0.0.1).SuffixOrigin -ne "Dhcp") {Start-Sleep -seconds 10} }
}
function New-VMsession
{
[CmdletBinding()]
Param(
[Parameter(Mandatory = $true, Position = 0)]
[string] $MachineName,
[Parameter(Position = 1)]
[PScredential] $Cred
)
$SleepTimer = 5
do {
$s = New-PSSession -VMName $MachineName -Credential $Cred -ErrorAction Ignore
If(!$s){Start-Sleep -Seconds $SleepTimer
Write-Verbose "Waiting to get pssession to $MachineName on $MachineIP sleeping for $SleepTimer sec"}
$SleepTimer = [math]::floor(($SleepTimer *3)/2)
}
until($s)
Return $s
}
function Complete-HostConfig
{
[CmdletBinding()]
param( [PSCustomObject]
$configuration
)
.$(Join-Path -Path $configuration.ScriptLocation -ChildPath 'Configuration\LabHostResourcesConfig.ps1') -configuration $configuration
}
function New-LabVM
{
[CmdletBinding()]
param([Parameter(Mandatory)]
[string]$VMName,
[Parameter(Mandatory)]
[string]$SysPrepImage,
[PSCustomObject] $configuration
)
.$(Join-Path -Path $configuration.ScriptLocation -ChildPath 'Configuration\LabHostCreateVMConfig.ps1') -VMName $VMName -configuration $configuration -SysPrepImage $SysPrepImage
}
function Add-LabVMtoDomain
{
[CmdletBinding()]
param([Parameter(Mandatory)]
[string]$VMName,
[PSCustomObject]
$configuration
)
$localAdminCred = New-Cred -userPass $configuration.localAdminPass -userName 'administrator'
$DomCred = New-Cred -userPass $configuration.domainAdminPass -UserName "$($Configuration.domainname)\Administrator"
#Wait for DC to finalize DHCP configuration
WaitForDHCPPSDirect -VMName $VMName -cred $localAdminCred
WaitForPSDirect -VMName $configuration.DCMachineName -cred $DomCred
Invoke-Command -VMName $configuration.DCMachineName -Credential $DomCred -ScriptBlock {djoin /provision /domain $using:configuration.domainname /machine $using:VMName /savefile c:\$using:VMName.txt} -ErrorAction Ignore
#Create offline domain join files so we can join Each VM later
$DCSession= New-VMsession -MachineName $configuration.DCMachineName -Cred $DomCred
Copy-Item -Path c:\$VMName.txt -Destination $configuration.DomainJoinPath -FromSession $DCSession
Remove-PSSession $DCSession -ErrorAction Ignore
#Copy all the DSC resources we will leverage
$ServerSession = New-VMsession -MachineName $VMName -Cred $localAdminCred
Copy-Item -Path "$(Join-Path -Path $configuration.DSCResourceSource -ChildPath 'DCResources.zip')" -Destination "$(Join-Path -Path $configuration.DSCResourceDest -ChildPath 'DCResources.zip')"-ToSession $ServerSession
Invoke-Command -VMName $VMName -Credential $localAdminCred -ScriptBlock {Expand-Archive -Path "$(Join-Path -Path $args -ChildPath 'DCResources.zip')" -DestinationPath "$args" -Force} -ArgumentList $configuration.DSCResourceDest
Copy-Item -Path "$(Join-Path -Path $configuration.DSCResourceSource -ChildPath 'CertResources.zip')" -Destination "$(Join-Path -Path $configuration.DSCResourceDest -ChildPath 'CertResources.zip')"-ToSession $ServerSession
Invoke-Command -VMName $VMName -Credential $localAdminCred -ScriptBlock {Expand-Archive -Path "$(Join-Path -Path $args -ChildPath 'CertResources.zip')" -DestinationPath "$args" -Force} -ArgumentList $configuration.DSCResourceDest
Copy-Item -Path "$(Join-Path -Path $configuration.ScriptLocation -ChildPath 'Configuration\LabGuestAddtoDomainDSCConfig.ps1')" -Destination "$(Join-Path -Path $configuration.DSCResourceDest -ChildPath 'LabGuestAddtoDomainDSCConfig.ps1')" -ToSession $ServerSession
Copy-Item -Path "$(Join-Path -Path $configuration.ScriptLocation -ChildPath 'Configuration\LabGuestPostDomainConfig.ps1')" -Destination "$(Join-Path -Path $configuration.DSCResourceDest -ChildPath 'LabGuestPostDomainConfig.ps1')" -ToSession $ServerSession
Copy-Item -Path "$(Join-Path -Path $configuration.DomainJoinPath -ChildPath "$VMName.txt")" -Destination "$(Join-Path -Path $configuration.DSCResourceDest -ChildPath "$VMName.txt")" -ToSession $ServerSession
#Kick of configuration to Join the Vm to the domain
Invoke-Command -VMName $VMName -Credential $localAdminCred -ScriptBlock {."$(Join-Path -Path $args[0] -ChildPath 'LabGuestAddtoDomainDSCConfig.ps1')" -MachineName $args[1] -configuration $args[2]} -ArgumentList $configuration.DSCResourceDest,$VMName, $configuration
Start-Sleep -Seconds 5
#Wait for VM to become available then complete the post configuration tasks
WaitForPSDirect -VMName $VMName -cred $DomCred
Invoke-Command -VMName $VMName -Credential $DomCred -ScriptBlock {."$(Join-Path -Path $args[0] -ChildPath 'LabGuestPostDomainConfig.ps1')" -MachineName $args[1] -configuration $args[2] -domainCred $args[3]} -ArgumentList $configuration.DSCResourceDest,$VMName, $configuration,$DomCred
}
function New-Domain
{
[CmdletBinding()]
param( [PSCustomObject]
$configuration
)
$localAdminCred = New-Cred -userPass $configuration.localAdminPass -userName 'administrator'
$DomCred = New-Cred -userPass $configuration.domainAdminPass -UserName "$($configuration.domainname)\Administrator"
if (Test-Path "$($configuration.ISOFolderPath)\en_sql_server_2016_enterprise_x64_dvd_8701793.iso")
{
Add-VMDvdDrive -VMName $configuration.DCMachineName -Path "$($configuration.ISOFolderPath)\en_sql_server_2016_enterprise_x64_dvd_8701793.iso"
}
if (Test-Path "$($configuration.ISOFolderPath)\en_windows_server_2016_x64_dvd_9327751.iso")
{
Add-VMDvdDrive -VMName $configuration.DCMachineName -Path "$($configuration.ISOFolderPath)\en_windows_server_2016_x64_dvd_9327751.iso"
}
WaitForPSDirect -VMName $configuration.DCMachineName -cred $localAdminCred
$DCSession = New-VMsession -MachineName $configuration.DCMachineName -Cred $localAdminCred
Copy-Item -Path "$(Join-Path -Path $configuration.ScriptLocation -ChildPath 'Configuration\LabGuestPreDomainConfig.ps1')" -Destination "$(Join-Path -Path $configuration.DSCResourceDest -ChildPath 'LabGuestPreDomainConfig.ps1')" -ToSession $DCSession
Copy-Item -Path "$(Join-Path -Path $configuration.DSCResourceSource -ChildPath 'DCResources.zip')" -Destination "$(Join-Path -Path $configuration.DSCResourceDest -ChildPath 'DCResources.zip')"-ToSession $DCSession
Invoke-Command -VMName $configuration.DCMachineName -Credential $localAdminCred -ScriptBlock {Expand-Archive -Path "$(Join-Path -Path $args -ChildPath 'DCResources.zip')" -DestinationPath "$args" -Force} -ArgumentList $configuration.DSCResourceDest
Invoke-Command -VMName $configuration.DCMachineName -Credential $localAdminCred -ScriptBlock {Remove-Item -Path "$(Join-Path -Path $args -ChildPath 'DCResources.zip')" -Force} -ArgumentList $configuration.DSCResourceDest
Invoke-Command -VMName $configuration.DCMachineName -Credential $localAdminCred -ScriptBlock {."$(Join-Path -Path $args[0] -ChildPath 'LabGuestPreDomainConfig.ps1')" -MachineName $Args[1] -configuration $Args[2] -domainCred $Args[3] -safemodeCred $Args[3]} -ArgumentList $configuration.DSCResourceDest,$configuration.DCMachineName,$configuration,$DomCred
}
function Stop-LabinaBox
{
[CmdletBinding()]
param( [string]
$configuration
)
$configurationData = Get-Content -Path $configuration -Raw | ConvertFrom-Json
Stop-VM -Name $configurationData.DCMachineName -Save
$configurationData.DomainJoinServer | ForEach-Object -process {
stop-Vm -name $_ -save
}
}
function Start-LabinaBox
{
[CmdletBinding()]
param( [string]
$configuration
)
$configurationData = Get-Content -Path $configuration -Raw | ConvertFrom-Json
Start-VM -name $configurationData.DCMachineName
$configurationData.DomainJoinServer | ForEach-Object -process {
Start-VM -name $_
}
}
function Remove-LabinaBox
{
[CmdletBinding()]
param( [string]
$configuration
)
$configurationData = Get-Content -Path $configuration -Raw | ConvertFrom-Json
$Servers = $configurationData.DomainJoinServer + $configurationData.DCMachineName
$Servers | ForEach-Object -process {
stop-Vm -name $_ -turnoff
Remove-VM -Name $_ -force
}
Remove-Item $configurationData.ChildFolderPath -Force -Recurse
}
function CheckPoint-LabinaBox
{
[CmdletBinding()]
param( [string]
$configuration
)
$configurationData = Get-Content -Path $configuration -Raw | ConvertFrom-Json
Get-VM -name $configurationData.DCMachineName | Checkpoint-VM
$configurationData.DomainJoinServer | ForEach-Object -process {
Get-VM -name $_ | CheckPoint-VM
}
}
function Remove-LabinaBoxSnapshot
{
[CmdletBinding()]
param( [PSCustomObject]
$configuration
)
$configurationData = Get-Content -Path $configuration -Raw | ConvertFrom-Json
Get-VM -name $configurationData.DCMachineName | Remove-VMSnapshot
$configurationData.DomainJoinServer | ForEach-Object -process {
Get-VM -name $_ | Remove-VMSnapshot
}
}
function New-LabinaBox
{
[CmdletBinding()]
param( [PSCustomObject]
$configuration
)
$configurationData = Get-Content -Path $configuration -Raw | ConvertFrom-Json
$start = Get-Date
Write-Verbose -Message "Lab Creation began at: $start"
$ExecutionPolicy = Get-ExecutionPolicy
if ($ExecutionPolicy -eq 'Restricted') {Set-ExecutionPolicy -ExecutionPolicy RemoteSigned -Force}
#Step 1. Setup lab host. Apply Configuration to the host to ensure we can create Vms
Complete-HostConfig -configuration $configurationData
#Step 2. Create domain controller VM
New-LabVM -VMName $configurationData.DCMachineName -SysPrepImage $configurationData.DCSysPrepDriveName -configuration $configurationData
#Step 3. Create each member server VM
$configurationdata.DomainJoinServer | ForEach-Object -Process {New-LabVM -configuration $configurationData -VMName $_ -Verbose -SysPrepImage $configurationData.sysPrepDriveName}
#Step 4. Apply domain controller DSC configuration
New-Domain -configuration $configurationData -verbose
#Step 5. Apply member server DSC configuration for each server
$configurationdata.DomainJoinServer | ForEach-Object -Process {Add-LabVMtoDomain -configuration $configurationData -VMName $_ -verbose}
$end = Get-Date
$diff = $end -$start
Write-Verbose -Message "Completed lab build @ $($end.ToLongTimeString())"
Write-Verbose -Message "Time to build lab: $("{0:N2}" -f ($diff.TotalMinutes)) minutes"
}
Export-ModuleMember -Function 'Stop-LabinaBox','Start-LabinaBox','CheckPoint-LabinaBox','Remove-LabinaBoxSnapshot','Remove-LabinaBox','New-LabinaBox'