Addition of functions and simplification
This commit is contained in:
Родитель
5c2680d030
Коммит
e1229178e6
|
@ -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
Двоичные данные
utility/LabInaBox/DSCResources/DCResources.zip
Двоичный файл не отображается.
Двоичные данные
utility/LabInaBox/DSCResources/DSC-data-driven-deployment.zip
Двоичные данные
utility/LabInaBox/DSCResources/DSC-data-driven-deployment.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'
|
Загрузка…
Ссылка в новой задаче