From 095e685dc6c9522c8b113fde949830fa4a87e63b Mon Sep 17 00:00:00 2001 From: Cory Wood Date: Tue, 23 Feb 2016 11:21:24 -0600 Subject: [PATCH 01/13] Created xGroupPolicy Module. --- .gitignore | 1 + .../MSFT_xGPInheritance.psm1 | 137 +++++++++ .../MSFT_xGPInheritance.schema.mof | 8 + .../MSFT_xGPOImport/MSFT_xGPOImport.psm1 | 104 +++++++ .../MSFT_xGPOImport.schema.mof | 12 + DSCResources/MSFT_xGPOLink/MSFT_xGPOLink.psm1 | 277 ++++++++++++++++++ .../MSFT_xGPOLink/MSFT_xGPOLink.schema.mof | 13 + README.md | 196 +++++++++++++ .../MSFT_xGPInheritance.Integration.tests.ps1 | 64 ++++ .../MSFT_xGPInheritance.config.ps1 | 16 + .../MSFT_xGPOImport.Integration.tests.ps1 | 68 +++++ Tests/Integration/MSFT_xGPOImport.config.ps1 | 25 ++ .../MSFT_xGPOLink.Integration.tests.ps1 | 68 +++++ Tests/Integration/MSFT_xGPOLink.config.ps1 | 23 ++ Tests/Unit/MSFT_xGPInheritance.Tests.ps1 | 163 +++++++++++ Tests/Unit/MSFT_xGPOImport.Tests.ps1 | 142 +++++++++ Tests/Unit/MSFT_xGPOLink.Tests.ps1 | 199 +++++++++++++ appveyor.yml | 69 +++++ xGroupPolicy.psd1 | Bin 0 -> 6672 bytes 19 files changed, 1585 insertions(+) create mode 100644 .gitignore create mode 100644 DSCResources/MSFT_xGPInheritance/MSFT_xGPInheritance.psm1 create mode 100644 DSCResources/MSFT_xGPInheritance/MSFT_xGPInheritance.schema.mof create mode 100644 DSCResources/MSFT_xGPOImport/MSFT_xGPOImport.psm1 create mode 100644 DSCResources/MSFT_xGPOImport/MSFT_xGPOImport.schema.mof create mode 100644 DSCResources/MSFT_xGPOLink/MSFT_xGPOLink.psm1 create mode 100644 DSCResources/MSFT_xGPOLink/MSFT_xGPOLink.schema.mof create mode 100644 README.md create mode 100644 Tests/Integration/MSFT_xGPInheritance.Integration.tests.ps1 create mode 100644 Tests/Integration/MSFT_xGPInheritance.config.ps1 create mode 100644 Tests/Integration/MSFT_xGPOImport.Integration.tests.ps1 create mode 100644 Tests/Integration/MSFT_xGPOImport.config.ps1 create mode 100644 Tests/Integration/MSFT_xGPOLink.Integration.tests.ps1 create mode 100644 Tests/Integration/MSFT_xGPOLink.config.ps1 create mode 100644 Tests/Unit/MSFT_xGPInheritance.Tests.ps1 create mode 100644 Tests/Unit/MSFT_xGPOImport.Tests.ps1 create mode 100644 Tests/Unit/MSFT_xGPOLink.Tests.ps1 create mode 100644 appveyor.yml create mode 100644 xGroupPolicy.psd1 diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..b03606a --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +DSCResource.Tests diff --git a/DSCResources/MSFT_xGPInheritance/MSFT_xGPInheritance.psm1 b/DSCResources/MSFT_xGPInheritance/MSFT_xGPInheritance.psm1 new file mode 100644 index 0000000..8bafaef --- /dev/null +++ b/DSCResources/MSFT_xGPInheritance/MSFT_xGPInheritance.psm1 @@ -0,0 +1,137 @@ +function Get-TargetResource +{ + [OutputType([Hashtable])] + param + ( + [parameter(Mandatory = $true)] + [string]$Target, + [string]$Domain, + [string]$Server, + [ValidateSet('Present','Absent')] + [string]$Ensure = 'Present' + ) + $Target = Test-TargetDN @PSBoundParameters + $targetResource = @{ + Target = $Target + Domain = $null + Server = $null + Ensure = $null + } + $params = @{Target = $Target} + if ($Domain) + { + $targetResource.Domain = $Domain + $params += @{Domain = $Domain} + } + if ($Server) + { + $targetResource.Server = $Server + $params += @{Server = $Server} + } + Import-Module GroupPolicy -Verbose:$false + Write-Verbose 'Getting Group Policy Inheritance' + $gpoInheritanceBlocked = (Get-GPInheritance @params).GpoInheritanceBlocked + if (!$gpoInheritanceBlocked) {$targetResource.Ensure = 'Present'} + else {$targetResource.Ensure = 'Absent'} + Write-Output $targetResource +} + +function Set-TargetResource +{ + param + ( + [parameter(Mandatory = $true)] + [string]$Target, + [string]$Domain, + [string]$Server, + [ValidateSet('Present','Absent')] + [string]$Ensure = 'Present' + ) + if ($Ensure -eq 'Present') + { + Write-Verbose 'Enabling Group Policy Inheritance' + $isBlocked = 'No' + } + else + { + Write-Verbose 'Disabling Group Policy Inheritance' + $isBlocked = 'Yes' + } + $Target = Test-TargetDN @PSBoundParameters + $params = @{ + Target = $Target + IsBlocked = $IsBlocked + } + if ($Domain) + { + $params += @{Domain = $Domain} + } + if ($Server) + { + $params += @{Server = $Server} + } + Import-Module GroupPolicy -Verbose:$false + $null = Set-GPInheritance @params +} + +function Test-TargetResource +{ +[OutputType([Boolean])] + param + ( + [parameter(Mandatory = $true)] + [string]$Target, + [string]$Domain, + [string]$Server, + [ValidateSet('Present','Absent')] + [string]$Ensure = 'Present' + ) + $targetResource = Get-TargetResource @PSBoundParameters + switch ($Ensure) + { + Present + { + if ($targetResource.Ensure -eq 'Present') {$true} + else {$false} + } + Absent + { + if ($targetResource.Ensure -eq 'Absent') {$true} + else {$false} + } + } +} + +function Test-TargetDN +{ + param + ( + [parameter(Mandatory = $true)] + [string]$Target, + [string]$Domain, + [string]$Server, + [ValidateSet('Present','Absent')] + [string]$Ensure = 'Present' + ) + $params = @{} + if ($Server) {$params += @{Server = $Server}} + Write-Verbose "Checking the Domain Distinguished Name is present on the Target Distinguished Name." + $domainDN = (Get-ADDomain @params).DistinguishedName + if ($Target -like "*$domainDN") + { + Write-Verbose "Target has full DN." + } + else + { + Write-Verbose "Adding the Domain Distinguished Name to the Target DN." + if ($Target.EndsWith(",")) + { + $Target = "$Target$domainDN" + } + else + { + $Target = "$Target,$domainDN" + } + } + $Target +} diff --git a/DSCResources/MSFT_xGPInheritance/MSFT_xGPInheritance.schema.mof b/DSCResources/MSFT_xGPInheritance/MSFT_xGPInheritance.schema.mof new file mode 100644 index 0000000..2a9aa12 --- /dev/null +++ b/DSCResources/MSFT_xGPInheritance/MSFT_xGPInheritance.schema.mof @@ -0,0 +1,8 @@ +[ClassVersion("1.0.0"), FriendlyName("xGPInheritance")] +class MSFT_xGPInheritance : OMI_BaseResource +{ + [Key] String Target; + [write] String Domain; + [write] String Server; + [write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] string Ensure; +}; diff --git a/DSCResources/MSFT_xGPOImport/MSFT_xGPOImport.psm1 b/DSCResources/MSFT_xGPOImport/MSFT_xGPOImport.psm1 new file mode 100644 index 0000000..c7c50e4 --- /dev/null +++ b/DSCResources/MSFT_xGPOImport/MSFT_xGPOImport.psm1 @@ -0,0 +1,104 @@ +function Get-TargetResource +{ + [OutputType([Hashtable])] + param + ( + [parameter(Mandatory = $true)] + [string]$TargetName, + [parameter(Mandatory = $true)] + [string]$Path, + [parameter(Mandatory = $true)] + [string]$BackupIdentity, + [ValidateSet('Name','Guid')] + [string]$BackupIdentityType = 'Name', + [string]$Domain, + [string]$MigrationTable, + [string]$Server, + [ValidateSet('Present')] + [string]$Ensure = 'Present' + ) + Import-Module GroupPolicy -Verbose:$false + $params = @{ + Name = $TargetName + ErrorAction = 'SilentlyContinue' + } + if ($Domain) {$params += @{Domain = $Domain}} + if ($Server) {$params += @{Server = $Server}} + Write-Verbose 'Getting GPO' + $gpo = Get-GPO @params + $targetResource = @{ + TargetName = $TargetName + Path = $Path + BackupIdentity = $BackupIdentity + BackupIdentityType = $BackupIdentityType + Domain = $null + MigrationTable = $null + Server = $null + Ensure = 'Absent' + } + if ($MigrationTable) {$targetResource.MigrationTable = $MigrationTable} + if ($Server) {$targetResource.Server = $Server} + if ($gpo) + { + $targetResource.Domain = $gpo.DomainName + $targetResource.Ensure = 'Present' + } + $targetResource +} + +function Set-TargetResource +{ + param + ( + [parameter(Mandatory = $true)] + [string]$TargetName, + [parameter(Mandatory = $true)] + [string]$Path, + [parameter(Mandatory = $true)] + [string]$BackupIdentity, + [ValidateSet('Name','Guid')] + [string]$BackupIdentityType = 'Name', + [string]$Domain, + [string]$MigrationTable, + [string]$Server, + [ValidateSet('Present')] + [string]$Ensure = 'Present' + ) + Import-Module GroupPolicy -Verbose:$false + $params = @{ + TargetName = $TargetName + Path = $Path + CreateIfNeeded = $true + } + if ($BackupIdentityType -eq 'Name') {$params += @{BackupGpoName = $BackupIdentity}} + else {$params += @{BackupId = $BackupIdentity}} + if ($Domain) {$params += @{Domain = $Domain}} + if ($MigrationTable) {$params += @{MigrationTable = $MigrationTable}} + if ($Server) {$params += @{Server = $Server}} + Write-Verbose 'Importing GPO' + $null = Import-GPO @params +} + +function Test-TargetResource +{ +[OutputType([Boolean])] + param + ( + [parameter(Mandatory = $true)] + [string]$TargetName, + [parameter(Mandatory = $true)] + [string]$Path, + [parameter(Mandatory = $true)] + [string]$BackupIdentity, + [ValidateSet('Name','Guid')] + [string]$BackupIdentityType = 'Name', + [string]$Domain, + [string]$MigrationTable, + [string]$Server, + [ValidateSet('Present')] + [string]$Ensure = 'Present' + ) + $targetResource = Get-TargetResource @PSBoundParameters + if ($targetResource.Ensure -eq 'Present') {$true} + else {$false} +} diff --git a/DSCResources/MSFT_xGPOImport/MSFT_xGPOImport.schema.mof b/DSCResources/MSFT_xGPOImport/MSFT_xGPOImport.schema.mof new file mode 100644 index 0000000..ab0e4af --- /dev/null +++ b/DSCResources/MSFT_xGPOImport/MSFT_xGPOImport.schema.mof @@ -0,0 +1,12 @@ +[ClassVersion("1.0.0"), FriendlyName("xGPOImport")] +class MSFT_xGPOImport : OMI_BaseResource +{ + [Key] String TargetName; + [required] String Path; + [required] String BackupIdentity; + [write,ValueMap{"Name", "Guid"},Values{"Name", "Guid"}] string BackupIdentityType; + [write] String Domain; + [write] String MigrationTable; + [write] String Server; + [write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] string Ensure; +}; diff --git a/DSCResources/MSFT_xGPOLink/MSFT_xGPOLink.psm1 b/DSCResources/MSFT_xGPOLink/MSFT_xGPOLink.psm1 new file mode 100644 index 0000000..d6ff65f --- /dev/null +++ b/DSCResources/MSFT_xGPOLink/MSFT_xGPOLink.psm1 @@ -0,0 +1,277 @@ +function Get-TargetResource { + [OutputType([Hashtable])] + param + ( + [parameter(Mandatory = $true)] + [string]$Identity, + [ValidateSet('Name','Guid')] + [string]$IdentityType = 'Name', + [parameter(Mandatory = $true)] + [string]$Target, + [string]$Domain, + [ValidateSet('Yes','No')] + [string]$Enforced, + [ValidateSet('Yes','No')] + [string]$LinkEnabled, + [int16]$Order, + [string]$Server, + [ValidateSet('Present','Absent')] + [string]$Ensure = 'Present' + ) + $target = Test-TargetDN @PSBoundParameters + $gpInheritanceparams = @{ + Target = $target + } + if ($Server) {$gpInheritanceparams += @{Server = $Server}} + if ($Domain) {$gpInheritanceparams += @{Domain = $Domain}} + Import-Module GroupPolicy -Verbose:$false + Write-Verbose 'Getting GPO Links' + $gpoLinks = (Get-GPInheritance @gpInheritanceparams).GpoLinks + $gpo = Get-GpoInfo @PSBoundParameters + $targetResource = @{ + Identity = $Identity + IdentityType = $IdentityType + Target = $Target + Domain = $null + Enforced = $null + LinkEnabled = $null + Order = $null + Server = $Server + Ensure = 'Absent' + } + if ($gpo) + { + # Using the GpoId attribute of the GPO Links instead of the + # Name attribute because the Name attribute may take a while + # to replicate to all DCs if the GPO was recently created. + $targetLink = $gpoLinks | where {$_.GpoId -eq $gpo.Id} + if ($targetLink) + { + if ($targetLink.Enabled) {$targetResource.LinkEnabled = 'Yes'} + else {$targetResource.LinkEnabled = 'No'} + if ($targetLink.Enforced) {$targetResource.Enforced = 'Yes'} + else {$targetResource.Enforced = 'No'} + $targetResource.Order = $targetLink.Order + $targetResource.Ensure = 'Present' + } + $targetResource.Domain = $gpo.DomainName + } + $targetResource +} + +function Set-TargetResource { + param + ( + [parameter(Mandatory = $true)] + [string]$Identity, + [ValidateSet('Name','Guid')] + [string]$IdentityType = 'Name', + [parameter(Mandatory = $true)] + [string]$Target, + [string]$Domain, + [ValidateSet('Yes','No')] + [string]$Enforced, + [ValidateSet('Yes','No')] + [string]$LinkEnabled, + [int16]$Order, + [string]$Server, + [ValidateSet('Present','Absent')] + [string]$Ensure = 'Present' + ) + Import-Module GroupPolicy -Verbose:$false + $targetResource = Get-TargetResource @PSBoundParameters + $gpo = Get-GpoInfo @PSBoundParameters + if ($Ensure -eq 'Present') + { + if ($targetResource.Ensure -eq 'Present') + { + $setParams = @{Target = $targetResource.Target} + if ($IdentityType -eq 'Name') + { + # Using the GpoId attribute of the GPO Links instead of the + # Name attribute because the Name attribute may take a while + # to replicate to all DCs if the GPO was recently created. + $setParams += @{Guid = $gpo.Id} + } + else {$setParams += @{Guid = $Identity}} + if ($Domain) {$setParams += @{Domain = $Domain}} + if ($Enforced -and $targetResource.Enforced -ne $Enforced) + { + $setParams += @{Enforced = $Enforced} + } + if ($LinkEnabled -and $targetResource.LinkEnabled -ne $LinkEnabled) + { + $setParams += @{LinkEnabled = $LinkEnabled} + } + if ($Order -and $targetResource.Order -ne $Order) + { + $setParams += @{Order = $Order} + } + if ($Server) {$setParams += @{Server = $Server}} + Write-Verbose 'Updating GPO Link' + Set-GPLink @setParams + } + else + { + $newParams = @{Target = $targetResource.Target} + if ($IdentityType -eq 'Name') + { + # Using the GpoId attribute of the GPO Links instead of the + # Name attribute because the Name attribute may take a while + # to replicate to all DCs if the GPO was recently created. + $newParams += @{Guid = $gpo.Id} + } + else {$newParams += @{Guid = $Identity}} + if ($Domain) {$setParams += @{Domain = $Domain}} + if ($Enforced) {$newParams += @{Enforced = $Enforced}} + if ($LinkEnabled) {$newParams += @{LinkEnabled = $LinkEnabled}} + if ($Order) {$newParams += @{Order = $Order}} + if ($Server) {$setParams += @{Server = $Server}} + Write-Verbose 'Creating GPO Link' + New-GPLink @newParams + } + } + else + { + $removeParams = @{Target = $targetResource.Target} + if ($IdentityType -eq 'Name') + { + # Using the GpoId attribute of the GPO Links instead of the + # Name attribute because the Name attribute may take a while + # to replicate to all DCs if the GPO was recently created. + $removeParams += @{Guid = $gpo.Id} + } + else {$removeParams += @{Guid = $Identity}} + if ($Domain) {$removeParams += @{Domain = $Domain}} + if ($Server) {$removeParams += @{Server = $Server}} + Write-Verbose 'Removing GPO Link' + Remove-GPLink @removeParams + } +} + +function Test-TargetResource { +[OutputType([Boolean])] + param + ( + [parameter(Mandatory = $true)] + [string]$Identity, + [ValidateSet('Name','Guid')] + [string]$IdentityType = 'Name', + [parameter(Mandatory = $true)] + [string]$Target, + [string]$Domain, + [ValidateSet('Yes','No')] + [string]$Enforced, + [ValidateSet('Yes','No')] + [string]$LinkEnabled, + [int16]$Order, + [string]$Server, + [ValidateSet('Present','Absent')] + [string]$Ensure = 'Present' + ) + $targetResource = Get-TargetResource @PSBoundParameters + $targetResourceInCompliance = $true + if ($Ensure -eq 'Present') + { + if ($targetResource.Ensure -eq 'Present') + { + if ($Enforced -and $targetResource.Enforced -ne $Enforced) + { + $targetResourceInCompliance = $false + } + if ($LinkEnabled -and $targetResource.LinkEnabled -ne $LinkEnabled) + { + $targetResourceInCompliance = $false + } + if ($Order -and $targetResource.Order -ne $Order) + { + $targetResourceInCompliance = $false + } + } + else {$targetResourceInCompliance = $false} + } + elseif ($targetResource.Ensure -eq 'Present') + { + $targetResourceInCompliance = $false + } + $targetResourceInCompliance +} + +function Test-TargetDN +{ + param + ( + [parameter(Mandatory = $true)] + [string]$Identity, + [ValidateSet('Name','Guid')] + [string]$IdentityType = 'Name', + [parameter(Mandatory = $true)] + [string]$Target, + [string]$Domain, + [ValidateSet('Yes','No')] + [string]$Enforced, + [ValidateSet('Yes','No')] + [string]$LinkEnabled, + [int16]$Order, + [string]$Server, + [ValidateSet('Present','Absent')] + [string]$Ensure = 'Present' + ) + $params = @{} + if ($Server) {$params += @{Server = $Server}} + Write-Verbose "Checking the Domain Distinguished Name is present on the Target Distinguished Name." + $domainDN = (Get-ADDomain @params).DistinguishedName + if ($Target -like "*$domainDN") + { + Write-Verbose "Target has full DN." + } + else + { + Write-Verbose "Adding the Domain Distinguished Name to the Target DN." + if ($Target.EndsWith(",")) + { + $Target = "$Target$domainDN" + } + else + { + $Target = "$Target,$domainDN" + } + } + $Target +} + +function Get-GpoInfo +{ + param + ( + [parameter(Mandatory = $true)] + [string]$Identity, + [ValidateSet('Name','Guid')] + [string]$IdentityType = 'Name', + [parameter(Mandatory = $true)] + [string]$Target, + [string]$Domain, + [ValidateSet('Yes','No')] + [string]$Enforced, + [ValidateSet('Yes','No')] + [string]$LinkEnabled, + [int16]$Order, + [string]$Server, + [ValidateSet('Present','Absent')] + [string]$Ensure = 'Present' + ) + $gpoParams = @{} + if ($Server) + { + $gpoParams += @{Server = $Server} + } + if ($Domain) + { + $gpoParams += @{Domain = $Domain} + } + if ($IdentityType -eq 'Name') {$gpoParams += @{Name = $Identity}} + else {$gpoParams += @{Guid = $Identity}} + Import-Module GroupPolicy -Verbose:$false + Write-Verbose 'Getting GPO' + Get-GPO @gpoParams +} diff --git a/DSCResources/MSFT_xGPOLink/MSFT_xGPOLink.schema.mof b/DSCResources/MSFT_xGPOLink/MSFT_xGPOLink.schema.mof new file mode 100644 index 0000000..975773e --- /dev/null +++ b/DSCResources/MSFT_xGPOLink/MSFT_xGPOLink.schema.mof @@ -0,0 +1,13 @@ +[ClassVersion("1.0.0"), FriendlyName("xGPOLink")] +class MSFT_xGPOLink : OMI_BaseResource +{ + [Key] String Identity; + [Write,ValueMap{"Name", "Guid"},Values{"Name", "Guid"}] String IdentityType; + [Key] String Target; + [Write] String Domain; + [Write,ValueMap{"Yes", "No"},Values{"Yes", "No"}] String Enforced; + [Write,ValueMap{"Yes", "No"},Values{"Yes", "No"}] String LinkEnabled; + [Write] Sint16 Order; + [Write] String Server; + [Write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] String Ensure; +}; diff --git a/README.md b/README.md new file mode 100644 index 0000000..8b80e10 --- /dev/null +++ b/README.md @@ -0,0 +1,196 @@ +{{AppVeyor build status badge for master branch}} + +# xGroupPolicy + +The **xGroupPolicy** module contains DSC resources for configuring Group Policy. + +## Contributing +Please check out common DSC Resources [contributing guidelines](https://github.com/PowerShell/DscResource.Kit/blob/master/CONTRIBUTING.md). + +## Resources + +* **xGPInheritance** blocks or unblocks inheritance for a specified domain or organizational unit (OU). +* **xGPOImport** imports the Group Policy settings from a backed-up GPO into a new GPO. It won't import settings into an existing GPO. +* **xGPOLink** links a GPO to a site, domain, or organizational unit (OU). + +### xGPInheritance + +* **Target**: Specifies the domain or the OU for which to block or unblock inheritance by its LDAP distinguished name. You can also leave off the domain part of the distinguished name and it will be generated automatically. See the example below. +* **Domain**: Optional. Specifies the domain to run against. +* **Server**: Optional. Specifies the name of the domain controller that this resource contacts to complete the operation. You can specify either the fully qualified domain name (FQDN) or the host name. +* **Ensure**: Whether inheritance should be blocked (Absent) or unblocked (Present). Defaults to Present. + +### xGPOImport + +* **TargetName**: Specifies the display name of the GPO into which the settings are to be imported. +* **Path**: Specifies the path to the backup directory. +* **BackupIdentity**: Specifies the display name or backup ID of the backed-up GPO from which to import the settings. +* **BackupIdentityType**: Specifies the type of the BackupIdentity (Name or Guid). Defaults to Name. +* **Domain**: Optional. Specifies the domain to run against. +* **MigrationTable**: Specifies the path to a migration table file. +* **Server**: Optional. Specifies the name of the domain controller that this resource contacts to complete the operation. You can specify either the fully qualified domain name (FQDN) or the host name. +* **Ensure**: Must be Present. Defaults to Present. + +### xGPOLink + +* **Identity**: Specifies the GPO to link by its display name or GUID. +* **IdentityType**: Specifies the type of the Identity (Name or Guid). Defaults to Name. +* **Target**: Specifies the LDAP distinguished name of the site, domain, or OU to which to link the GPO. You can also leave off the domain part of the distinguished name and it will be generated automatically. See the example below. +* **Domain**: Optional. Specifies the domain to run against. +* **Enforced**: Specifies whether the GPO link is enforced. You can specify Yes or No. Defaults to No. +* **LinkEnabled**: Specifies whether the GPO link is enabled. You can specify Yes or No. Defaults to Yes. +* **Order**: Specifies the link order for the GPO link. You can specify a number that is between one and the current number of GPO links to the target site, domain, or OU, plus one. +* **Server**: Optional. Specifies the name of the domain controller that this resource contacts to complete the operation. You can specify either the fully qualified domain name (FQDN) or the host name. +* **Ensure**: Whether the GPO Link should exist (Present) or not (Absent). Defaults to Present. + +## Versions + +### Unreleased + +### 1.0.0.0 + +* Initial release with the following resources: + * xGPInheritance + * xGPOImport + * xGPOLink + +## Examples +### Block inheritance on OU + +In this example, we block inheritance on the Example OU. + +``` +configuration BlockInheritance +{ + Import-DscResource -Module xGPInheritance + + Node $AllNodes.NodeName + { + xGPInheritance ExampleOU + { + Target = 'OU=Example,DC=testdomain,DC=local' + Ensure = 'Absent' + } + } +} +BlockInheritance +``` + +### Unblock inheritance on OU + +In this example, we unblock inheritance on the Example OU. We also leave off the domain part of the OU DN so it's generated automatically for us. + +``` +configuration UnblockInheritance +{ + Import-DscResource -Module xGPInheritance + + Node $AllNodes.NodeName + { + xGPInheritance ExampleOU + { + Target = 'OU=Example,' + Ensure = 'Absent' + } + } +} +UnblockInheritance +``` + +### Import Group Policy Settings by Name with Migration Table + +In this example, we import group policy settings into the Example GPO by specifying the backup name. We also use a migration table. + +``` +configuration ImportByName +{ + Import-DscResource -Module xGPOImport + + Node $AllNodes.NodeName + { + xGPOImport ExampleOU + { + TargetName = 'Example' + Path = "C:\GPO Backups\Example" + BackupIdentity = 'Example' + BackupIdentityType = 'Name' + MigrationTable = 'C:\GPO Backups\ExampleMigTable.mitable' + Ensure = 'Present' + } + } +} +ImportByName +``` + +### Import Group Policy Settings by GUID + +In this example, we import group policy settings into the Example GPO by specifying the backup GUID. + +``` +configuration ImportByGuid +{ + Import-DscResource -Module xGPOImport + + Node $AllNodes.NodeName + { + xGPOImport ExampleOU + { + TargetName = 'Example' + Path = "C:\GPO Backups\Example" + BackupIdentity = '7b230cb8-67fc-433d-812f-c93b53310dcf' + BackupIdentityType = 'Guid' + Ensure = 'Present' + } + } +} +ImportByGuid +``` + +### Link and Enforce GPO by Name. + +In this example, we link the Example GPO by name to the Example OU and enforce the link. We also change the link order to 1. + +``` +configuration LinkEnforcedGPOByName +{ + Import-DscResource -Module xGPOLink + + Node $AllNodes.NodeName + { + xGPOLink ExampleOU + { + Identity = 'Example' + IdentityType = 'Name' + Target = 'OU=Example,DC=testdomain,DC=local' + Enforced = 'Yes' + Order = 1 + Ensure = 'Present' + } + } +} +LinkEnforcedGPOByName +``` + +### Link GPO by GUID and Disable Link. + +In this example, we link a GPO by GUID to the Example OU and disable the link. We also leave off the domain part of the OU DN so it's generated automatically for us. + +``` +configuration LinkEnforcedGPOByName +{ + Import-DscResource -Module xGPOLink + + Node $AllNodes.NodeName + { + xGPOLink ExampleOU + { + Identity = '9b74f3ec-a20e-4567-a1cd-f0b13a339037' + IdentityType = 'Guid' + Target = 'OU=Example,' + LinkEnabled = 'No' + Ensure = 'Present' + } + } +} +LinkEnforcedGPOByName +``` \ No newline at end of file diff --git a/Tests/Integration/MSFT_xGPInheritance.Integration.tests.ps1 b/Tests/Integration/MSFT_xGPInheritance.Integration.tests.ps1 new file mode 100644 index 0000000..f7217d6 --- /dev/null +++ b/Tests/Integration/MSFT_xGPInheritance.Integration.tests.ps1 @@ -0,0 +1,64 @@ +$Global:DSCModuleName = 'xGroupPolicy' +$Global:DSCResourceName = 'MSFT_xGPInheritance' +# /TODO + +#region HEADER +[String] $moduleRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $Script:MyInvocation.MyCommand.Path)) +if ( (-not (Test-Path -Path (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests'))) -or ` + (-not (Test-Path -Path (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1'))) ) +{ + & git @('clone','https://github.com/PowerShell/DscResource.Tests.git',(Join-Path -Path $moduleRoot -ChildPath '\DSCResource.Tests\')) +} +else +{ + & git @('-C',(Join-Path -Path $moduleRoot -ChildPath '\DSCResource.Tests\'),'pull') +} +Import-Module (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1') -Force +$TestEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $Global:DSCModuleName ` + -DSCResourceName $Global:DSCResourceName ` + -TestType Integration +#endregion + +# TODO: Other Init Code Goes Here... + +# Using try/finally to always cleanup even if something awful happens. +try +{ + #region Integration Tests + $ConfigFile = Join-Path -Path $PSScriptRoot -ChildPath "$($Global:DSCResourceName).config.ps1" + . $ConfigFile + + Describe "$($Global:DSCResourceName)_Integration" { + #region DEFAULT TESTS + It 'Should compile without throwing' { + { + Invoke-Expression -Command "$($Global:DSCResourceName)_Config -OutputPath `$TestEnvironment.WorkingFolder" + Start-DscConfiguration -Path $TestEnvironment.WorkingFolder ` + -ComputerName localhost -Wait -Verbose -Force + } | Should not throw + } + + It 'should be able to call Get-DscConfiguration without throwing' { + { Get-DscConfiguration -Verbose -ErrorAction Stop } | Should Not throw + } + #endregion + + It 'Should have set the resource and all the parameters should match' { + $current = Get-DscConfiguration + $current.Target | Should Be $GPInheritance.Target + $current.Server | Should Be $GPInheritance.Server + $current.Ensure | Should Be $GPInheritance.Ensure + } + } + #endregion + +} +finally +{ + #region FOOTER + Restore-TestEnvironment -TestEnvironment $TestEnvironment + #endregion + + # TODO: Other Optional Cleanup Code Goes Here... +} diff --git a/Tests/Integration/MSFT_xGPInheritance.config.ps1 b/Tests/Integration/MSFT_xGPInheritance.config.ps1 new file mode 100644 index 0000000..b05077c --- /dev/null +++ b/Tests/Integration/MSFT_xGPInheritance.config.ps1 @@ -0,0 +1,16 @@ +$ou = 'OU=Test OU,DC=testdomain,DC=local' +$GPInheritance = @{ + Target = $ou + Server = 'localhost' + Ensure = 'Present' +} +configuration 'MSFT_xGPInheritance_config' { + Import-DscResource -Name 'MSFT_xGPInheritance' + node localhost { + xGPInheritance Integration_Test { + Target = $GPInheritance.Target + Server = $GPInheritance.Server + Ensure = $GPInheritance.Ensure + } + } +} \ No newline at end of file diff --git a/Tests/Integration/MSFT_xGPOImport.Integration.tests.ps1 b/Tests/Integration/MSFT_xGPOImport.Integration.tests.ps1 new file mode 100644 index 0000000..6903d47 --- /dev/null +++ b/Tests/Integration/MSFT_xGPOImport.Integration.tests.ps1 @@ -0,0 +1,68 @@ +$Global:DSCModuleName = 'xGroupPolicy' +$Global:DSCResourceName = 'MSFT_xGPOImport' +# /TODO + +#region HEADER +[String] $moduleRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $Script:MyInvocation.MyCommand.Path)) +if ( (-not (Test-Path -Path (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests'))) -or ` + (-not (Test-Path -Path (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1'))) ) +{ + & git @('clone','https://github.com/PowerShell/DscResource.Tests.git',(Join-Path -Path $moduleRoot -ChildPath '\DSCResource.Tests\')) +} +else +{ + & git @('-C',(Join-Path -Path $moduleRoot -ChildPath '\DSCResource.Tests\'),'pull') +} +Import-Module (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1') -Force +$TestEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $Global:DSCModuleName ` + -DSCResourceName $Global:DSCResourceName ` + -TestType Integration +#endregion + +# TODO: Other Init Code Goes Here... + +# Using try/finally to always cleanup even if something awful happens. +try +{ + #region Integration Tests + $ConfigFile = Join-Path -Path $PSScriptRoot -ChildPath "$($Global:DSCResourceName).config.ps1" + . $ConfigFile + + Describe "$($Global:DSCResourceName)_Integration" { + #region DEFAULT TESTS + It 'Should compile without throwing' { + { + Invoke-Expression -Command "$($Global:DSCResourceName)_Config -OutputPath `$TestEnvironment.WorkingFolder" + Start-DscConfiguration -Path $TestEnvironment.WorkingFolder ` + -ComputerName localhost -Wait -Verbose -Force + } | Should not throw + } + + It 'should be able to call Get-DscConfiguration without throwing' { + { Get-DscConfiguration -Verbose -ErrorAction Stop } | Should Not throw + } + #endregion + + It 'Should have set the resource and all the parameters should match' { + $current = Get-DscConfiguration + $current.TargetName | Should Be $GPO.TargetName + $current.Path | Should Be $GPO.Path + $current.BackupIdentity | Should Be $GPO.BackupIdentity + $current.BackupIdentityType | Should Be $GPO.BackupIdentityType + $current.Domain | Should Be $GPO.Domain + $current.MigrationTable | Should Be $GPO.MigrationTable + $current.Server | Should Be $GPO.Server + } + } + #endregion + +} +finally +{ + #region FOOTER + Restore-TestEnvironment -TestEnvironment $TestEnvironment + #endregion + + # TODO: Other Optional Cleanup Code Goes Here... +} diff --git a/Tests/Integration/MSFT_xGPOImport.config.ps1 b/Tests/Integration/MSFT_xGPOImport.config.ps1 new file mode 100644 index 0000000..0b9068b --- /dev/null +++ b/Tests/Integration/MSFT_xGPOImport.config.ps1 @@ -0,0 +1,25 @@ +$gpoName = 'Test GPO' +$domainName = 'testdomain.local' +$GPO = @{ + TargetName = $gpoName + Path = "C:\Test Path\GPO Backups\$gpoName" + BackupIdentity = $gpoName + BackupIdentityType = 'Name' + Domain = $domainName + MigrationTable = 'C:\Test Path\GPO Backups\MigTable.mitable' + Server = 'localhost' +} +configuration 'MSFT_xGPOImport_config' { + Import-DscResource -Name 'MSFT_xGPOImport' + node localhost { + xGPOImport Integration_Test { + TargetName = $GPO.TargetName + Path = $GPO.Path + BackupIdentity = $GPO.BackupIdentity + BackupIdentityType = $GPO.BackupIdentityType + Domain = $GPO.Domain + MigrationTable = $GPO.MigrationTable + Server = $GPO.Server + } + } +} \ No newline at end of file diff --git a/Tests/Integration/MSFT_xGPOLink.Integration.tests.ps1 b/Tests/Integration/MSFT_xGPOLink.Integration.tests.ps1 new file mode 100644 index 0000000..740a783 --- /dev/null +++ b/Tests/Integration/MSFT_xGPOLink.Integration.tests.ps1 @@ -0,0 +1,68 @@ +$Global:DSCModuleName = 'xGroupPolicy' +$Global:DSCResourceName = 'MSFT_xGPOLink' +# /TODO + +#region HEADER +[String] $moduleRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $Script:MyInvocation.MyCommand.Path)) +if ( (-not (Test-Path -Path (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests'))) -or ` + (-not (Test-Path -Path (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1'))) ) +{ + & git @('clone','https://github.com/PowerShell/DscResource.Tests.git',(Join-Path -Path $moduleRoot -ChildPath '\DSCResource.Tests\')) +} +else +{ + & git @('-C',(Join-Path -Path $moduleRoot -ChildPath '\DSCResource.Tests\'),'pull') +} +Import-Module (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1') -Force +$TestEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $Global:DSCModuleName ` + -DSCResourceName $Global:DSCResourceName ` + -TestType Integration +#endregion + +# TODO: Other Init Code Goes Here... + +# Using try/finally to always cleanup even if something awful happens. +try +{ + #region Integration Tests + $ConfigFile = Join-Path -Path $PSScriptRoot -ChildPath "$($Global:DSCResourceName).config.ps1" + . $ConfigFile + + Describe "$($Global:DSCResourceName)_Integration" { + #region DEFAULT TESTS + It 'Should compile without throwing' { + { + Invoke-Expression -Command "$($Global:DSCResourceName)_Config -OutputPath `$TestEnvironment.WorkingFolder" + Start-DscConfiguration -Path $TestEnvironment.WorkingFolder ` + -ComputerName localhost -Wait -Verbose -Force + } | Should not throw + } + + It 'should be able to call Get-DscConfiguration without throwing' { + { Get-DscConfiguration -Verbose -ErrorAction Stop } | Should Not throw + } + #endregion + + It 'Should have set the resource and all the parameters should match' { + $current = Get-DscConfiguration + $current.Identity | Should Be $GPOLink.Identity + $current.IdentityType | Should Be $GPOLink.IdentityType + $current.Target | Should Be $GPOLink.Target + $current.Enforced | Should Be $GPOLink.Enforced + $current.LinkEnabled | Should Be $GPOLink.LinkEnabled + $current.Order | Should Be $GPOLink.Order + $current.Ensure | Should Be $GPOLink.Ensure + } + } + #endregion + +} +finally +{ + #region FOOTER + Restore-TestEnvironment -TestEnvironment $TestEnvironment + #endregion + + # TODO: Other Optional Cleanup Code Goes Here... +} diff --git a/Tests/Integration/MSFT_xGPOLink.config.ps1 b/Tests/Integration/MSFT_xGPOLink.config.ps1 new file mode 100644 index 0000000..cf4892b --- /dev/null +++ b/Tests/Integration/MSFT_xGPOLink.config.ps1 @@ -0,0 +1,23 @@ +$GPOLink = @{ + Identity = 'Test GPO' + IdentityType = 'Name' + Target = 'OU=Test OU,DC=testdomain,DC=local' + Enforced = 'No' + LinkEnabled = 'Yes' + Order = 1 + Ensure = 'Present' +} +configuration 'MSFT_xGPOLink_config' { + Import-DscResource -Name 'MSFT_xGPOLink' + node localhost { + xGPOLink Integration_Test { + Identity = $GPOLink.Identity + IdentityType = $GPOLink.IdentityType + Target = $GPOLink.Target + Enforced = $GPOLink.Enforced + LinkEnabled = $GPOLink.LinkEnabled + Order = $GPOLink.Order + Ensure = $GPOLink.Ensure + } + } +} \ No newline at end of file diff --git a/Tests/Unit/MSFT_xGPInheritance.Tests.ps1 b/Tests/Unit/MSFT_xGPInheritance.Tests.ps1 new file mode 100644 index 0000000..41bc4c4 --- /dev/null +++ b/Tests/Unit/MSFT_xGPInheritance.Tests.ps1 @@ -0,0 +1,163 @@ +$Global:DSCModuleName = 'xGroupPolicy' +$Global:DSCResourceName = 'MSFT_xGPInheritance' + +#region HEADER +[String] $moduleRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $Script:MyInvocation.MyCommand.Path)) +if ( (-not (Test-Path -Path (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests'))) -or ` + (-not (Test-Path -Path (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1'))) ) +{ + & git @('clone','https://github.com/PowerShell/DscResource.Tests.git',(Join-Path -Path $moduleRoot -ChildPath '\DSCResource.Tests\')) +} +else +{ + & git @('-C',(Join-Path -Path $moduleRoot -ChildPath '\DSCResource.Tests\'),'pull') +} +Import-Module (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1') -Force +$TestEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $Global:DSCModuleName ` + -DSCResourceName $Global:DSCResourceName ` + -TestType Unit +#endregion + +# Begin Testing +try +{ + + #region Pester Tests + + # The InModuleScope command allows you to perform white-box unit testing on the internal + # (non-exported) code of a Script Module. + InModuleScope $Global:DSCResourceName { + + #region Pester Test Initialization + function Get-ADDomain {} + function Get-GPInheritance {} + function Set-GPInheritance {} + $rootDSE = 'DC=testdomain,DC=local' + $ou = 'OU=Test OU' + $presentParams = @{ + Target = "$ou,$rootDSE" + Server = 'localhost' + Ensure = 'Present' + } + $presentPartialOUParams = @{ + Target = "$ou," + Server = 'localhost' + Ensure = 'Present' + } + $absentParams = @{ + Target = "$ou,$rootDSE" + Server = 'localhost' + Ensure = 'Absent' + } + $fakeADDomain = @{DistinguishedName = $rootDSE} + $fakeGPInheritanceNotBlocked = @{GpoInheritanceBlocked = $false} + $fakeGPInheritanceBlocked = @{GpoInheritanceBlocked = $true} + #endregion + + + #region Function Get-TargetResource + Describe "$($Global:DSCResourceName)\Get-TargetResource" { + It 'Returns a "System.Collections.Hashtable" object type' { + Mock -CommandName Get-ADDomain -MockWith {$fakeADDomain} + Mock -CommandName Import-Module -MockWith {} + Mock -CommandName Get-GPInheritance -MockWith {$fakeGPInheritanceNotBlocked} + $targetResource = Get-TargetResource @presentParams + $targetResource -is [System.Collections.Hashtable] | Should Be $true + } + + It "Returns Ensure = Present when group policy inheritance is not blocked on the Target" { + Mock -CommandName Get-ADDomain -MockWith {$fakeADDomain} + Mock -CommandName Import-Module -MockWith {} + Mock -CommandName Get-GPInheritance -MockWith {$fakeGPInheritanceNotBlocked} + $targetResource = Get-TargetResource @presentParams + $targetResource.Ensure | Should Be 'Present' + } + + It "Returns Ensure = Absent when group policy inheritance is blocked on the Target" { + Mock -CommandName Get-ADDomain -MockWith {$fakeADDomain} + Mock -CommandName Import-Module -MockWith {} + Mock -CommandName Get-GPInheritance -MockWith {$fakeGPInheritanceBlocked} + $targetResource = Get-TargetResource @presentParams + $targetResource.Ensure | Should Be 'Absent' + } + } + #endregion + + + #region Function Test-TargetResource + Describe "$($Global:DSCResourceName)\Test-TargetResource" { + It 'Returns a "System.Boolean" object type' { + Mock -CommandName Get-ADDomain -MockWith {$fakeADDomain} + Mock -CommandName Import-Module -MockWith {} + Mock -CommandName Get-GPInheritance -MockWith {$fakeGPInheritanceNotBlocked} + $targetResource = Test-TargetResource @presentParams + $targetResource -is [System.Boolean] | Should Be $true + } + + It 'Passes when Ensure = Present and group policy inheritance is not blocked on the Target' { + Mock -CommandName Get-ADDomain -MockWith {$fakeADDomain} + Mock -CommandName Import-Module -MockWith {} + Mock -CommandName Get-GPInheritance -MockWith {$fakeGPInheritanceNotBlocked} + Test-TargetResource @presentParams | Should Be $true + } + + It 'Fails when Ensure = Present and group policy inheritance is blocked on the Target' { + Mock -CommandName Get-ADDomain -MockWith {$fakeADDomain} + Mock -CommandName Import-Module -MockWith {} + Mock -CommandName Get-GPInheritance -MockWith {$fakeGPInheritanceBlocked} + Test-TargetResource @presentParams | Should Be $false + } + + It 'Passes when Ensure = Absent and group policy inheritance is blocked on the Target' { + Mock -CommandName Get-ADDomain -MockWith {$fakeADDomain} + Mock -CommandName Import-Module -MockWith {} + Mock -CommandName Get-GPInheritance -MockWith {$fakeGPInheritanceBlocked} + Test-TargetResource @absentParams | Should Be $true + } + + It 'Fails when Ensure = Absent and group policy inheritance is not blocked on the Target' { + Mock -CommandName Get-ADDomain -MockWith {$fakeADDomain} + Mock -CommandName Import-Module -MockWith {} + Mock -CommandName Get-GPInheritance -MockWith {$fakeGPInheritanceNotBlocked} + Test-TargetResource @absentParams | Should Be $false + } + } + #endregion + + + #region Function Set-TargetResource + Describe "$($Global:DSCResourceName)\Set-TargetResource" { + It "Calls Import-GPO once" { + Mock -CommandName Get-ADDomain -MockWith {$fakeADDomain} + Mock -CommandName Import-Module -MockWith {} + Mock -CommandName Set-GPInheritance -MockWith {} + Set-TargetResource @presentParams + Assert-MockCalled -CommandName Set-GPInheritance -Times 1 -Exactly -Scope It + } + } + #endregion + + + #region Function Test-TargetDN + Describe "$($Global:DSCResourceName)\Test-TargetDN" { + It "Returns $ou,$rootDSE when given partial OU DN" { + Mock -CommandName Get-ADDomain -MockWith {$fakeADDomain} + Test-TargetDN @presentPartialOUParams | Should Be "$ou,$rootDSE" + } + + It "Returns $ou,$rootDSE when given full OU DN" { + Mock -CommandName Get-ADDomain -MockWith {$fakeADDomain} + Test-TargetDN @presentParams | Should Be "$ou,$rootDSE" + } + } + #endregion + } + #endregion +} +finally +{ + #region FOOTER + Restore-TestEnvironment -TestEnvironment $TestEnvironment + #endregion +} diff --git a/Tests/Unit/MSFT_xGPOImport.Tests.ps1 b/Tests/Unit/MSFT_xGPOImport.Tests.ps1 new file mode 100644 index 0000000..6a20a81 --- /dev/null +++ b/Tests/Unit/MSFT_xGPOImport.Tests.ps1 @@ -0,0 +1,142 @@ +$Global:DSCModuleName = 'xGroupPolicy' +$Global:DSCResourceName = 'MSFT_xGPOImport' + +#region HEADER +[String] $moduleRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $Script:MyInvocation.MyCommand.Path)) +if ( (-not (Test-Path -Path (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests'))) -or ` + (-not (Test-Path -Path (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1'))) ) +{ + & git @('clone','https://github.com/PowerShell/DscResource.Tests.git',(Join-Path -Path $moduleRoot -ChildPath '\DSCResource.Tests\')) +} +else +{ + & git @('-C',(Join-Path -Path $moduleRoot -ChildPath '\DSCResource.Tests\'),'pull') +} +Import-Module (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1') -Force +$TestEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $Global:DSCModuleName ` + -DSCResourceName $Global:DSCResourceName ` + -TestType Unit +#endregion + +# Begin Testing +try +{ + + #region Pester Tests + + # The InModuleScope command allows you to perform white-box unit testing on the internal + # (non-exported) code of a Script Module. + InModuleScope $Global:DSCResourceName { + + #region Pester Test Initialization + function Get-GPO {} + function Import-GPO {} + $gpoName = 'Test GPO' + $domainName = 'testdomain.local' + $testParams = @{ + TargetName = $gpoName + Path = "C:\Test Path\GPO Backups\$gpoName" + BackupIdentity = $gpoName + BackupIdentityType = 'Name' + Domain = $domainName + MigrationTable = 'C:\Test Path\GPO Backups\MigTable.mitable' + Server = 'TestServer' + } + $fakeGPO = @{ + DisplayName = $gpoName + DomainName = $domainName + } + #endregion + + + #region Function Get-TargetResource + Describe "$($Global:DSCResourceName)\Get-TargetResource" { + It 'Returns a "System.Collections.Hashtable" object type' { + Mock -CommandName Import-Module -MockWith {} + Mock -CommandName Get-GPO -MockWith {return $fakeGPO} + $targetResource = Get-TargetResource @testParams + $targetResource -is [System.Collections.Hashtable] | Should Be $true + } + + It "Returns Ensure = Present when GPO is found" { + Mock -CommandName Import-Module -MockWith {} + Mock -CommandName Get-GPO -MockWith {return $fakeGPO} + $targetResource = Get-TargetResource @testParams + $targetResource.Ensure | Should Be 'Present' + } + + It "Returns TargetName = $($testParams.TargetName) when GPO is found" { + Mock -CommandName Import-Module -MockWith {} + Mock -CommandName Get-GPO -MockWith {return $fakeGPO} + $targetResource = Get-TargetResource @testParams + $targetResource.TargetName | Should Be $testParams.TargetName + } + + It "Returns Domain = $($testParams.Domain) when GPO is found" { + Mock -CommandName Import-Module -MockWith {} + Mock -CommandName Get-GPO -MockWith {return $fakeGPO} + $targetResource = Get-TargetResource @testParams + $targetResource.Domain | Should Be $testParams.Domain + } + + It "Returns Ensure = Absent when GPO is not found" { + Mock -CommandName Import-Module -MockWith {} + Mock -CommandName Get-GPO -MockWith {} + $targetResource = Get-TargetResource @testParams + $targetResource.Ensure | Should Be 'Absent' + } + + It "Returns an empty Domain when GPO is not found" { + Mock -CommandName Import-Module -MockWith {} + Mock -CommandName Get-GPO -MockWith {} + $targetResource = Get-TargetResource @testParams + $targetResource.Domain | Should Be $null + } + } + #endregion + + + #region Function Test-TargetResource + Describe "$($Global:DSCResourceName)\Test-TargetResource" { + It 'Returns a "System.Boolean" object type' { + Mock -CommandName Import-Module -MockWith {} + Mock -CommandName Get-GPO -MockWith {return $fakeGPO} + $targetResource = Test-TargetResource @testParams + $targetResource -is [System.Boolean] | Should Be $true + } + + It 'Passes when GPO found' { + Mock -CommandName Import-Module -MockWith {} + Mock -CommandName Get-GPO -MockWith {return $fakeGPO} + Test-TargetResource @testParams | Should Be $true + } + + It 'Fails when GPO not found' { + Mock -CommandName Import-Module -MockWith {} + Mock -CommandName Get-GPO -MockWith {} + Test-TargetResource @testParams | Should Be $false + } + } + #endregion + + + #region Function Set-TargetResource + Describe "$($Global:DSCResourceName)\Set-TargetResource" { + It "Calls Import-GPO once" { + Mock -CommandName Import-Module -MockWith {} + Mock -CommandName Import-GPO -MockWith {} + Set-TargetResource @testParams + Assert-MockCalled -CommandName Import-GPO -Times 1 -Exactly -Scope It + } + } + #endregion + } + #endregion +} +finally +{ + #region FOOTER + Restore-TestEnvironment -TestEnvironment $TestEnvironment + #endregion +} diff --git a/Tests/Unit/MSFT_xGPOLink.Tests.ps1 b/Tests/Unit/MSFT_xGPOLink.Tests.ps1 new file mode 100644 index 0000000..a25d220 --- /dev/null +++ b/Tests/Unit/MSFT_xGPOLink.Tests.ps1 @@ -0,0 +1,199 @@ +$Global:DSCModuleName = 'xGroupPolicy' +$Global:DSCResourceName = 'MSFT_xGPOLink' + +#region HEADER +[String] $moduleRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $Script:MyInvocation.MyCommand.Path)) +if ( (-not (Test-Path -Path (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests'))) -or ` + (-not (Test-Path -Path (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1'))) ) +{ + & git @('clone','https://github.com/PowerShell/DscResource.Tests.git',(Join-Path -Path $moduleRoot -ChildPath '\DSCResource.Tests\')) +} +else +{ + & git @('-C',(Join-Path -Path $moduleRoot -ChildPath '\DSCResource.Tests\'),'pull') +} +Import-Module (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1') -Force +$TestEnvironment = Initialize-TestEnvironment ` + -DSCModuleName $Global:DSCModuleName ` + -DSCResourceName $Global:DSCResourceName ` + -TestType Unit +#endregion + +# Begin Testing +try +{ + + #region Pester Tests + + # The InModuleScope command allows you to perform white-box unit testing on the internal + # (non-exported) code of a Script Module. + InModuleScope $Global:DSCResourceName { + + #region Pester Test Initialization + function Get-ADDomain {} + function Get-GPO {} + function Get-GPInheritance {} + function New-GPLink {} + function Set-GPLink {} + function Remove-GPLink {} + $gpoName = 'Test GPO' + $gpoId = '8451f164-0cff-4d3f-b4d1-6a54640c80ae' + $rootDSE = 'DC=testdomain,DC=local' + $ou = 'OU=Test OU' + $domainName = 'testdomain.local' + $presentParams = @{ + Identity = $gpoName + IdentityType = 'Name' + Target = "$ou,$rootDSE" + Domain = $domainName + Enforced = 'No' + LinkEnabled = 'Yes' + Order = 1 + Ensure = 'Present' + } + $absentParams = $presentParams.Clone() + $absentParams.Ensure = 'Absent' + $gpInheritanceCorrectProperties = @{ + GpoLinks = @{ + GpoId = $gpoId + DisplayName = $gpoName + Enabled = $true + Enforced = $false + Target = "$ou,$rootDSE" + Order = 1 + } + } + $gpInheritanceIncorrectProperties = @{ + GpoLinks = @{ + GpoId = $gpoId + DisplayName = $gpoName + Enabled = $false + Enforced = $true + Target = "$ou,$rootDSE" + Order = 2 + } + } + $gpo = @{ + DisplayName = $gpoName + Id = $gpoId + DomainName = $domainName + } + #endregion + + + #region Function Get-TargetResource + Describe "$($Global:DSCResourceName)\Get-TargetResource" { + It 'Returns a "System.Collections.Hashtable" object type' { + Mock -CommandName Import-Module -MockWith {} + Mock -CommandName Get-GPInheritance -MockWith {} + Mock -CommandName Get-GPO -MockWith {return $gpo} + $targetResource = Get-TargetResource @presentParams + $targetResource -is [System.Collections.Hashtable] | Should Be $true + } + + It "Returns Ensure = Present when GPO Link is found" { + Mock -CommandName Import-Module -MockWith {} + Mock -CommandName Get-GPInheritance -MockWith {return $gpInheritanceCorrectProperties} + Mock -CommandName Get-GPO -MockWith {return $gpo} + $targetResource = Get-TargetResource @presentParams + $targetResource.Ensure | Should Be 'Present' + } + + It "Returns Ensure = Absent when GPO Link is not found" { + Mock -CommandName Import-Module -MockWith {} + Mock -CommandName Get-GPInheritance -MockWith {} + Mock -CommandName Get-GPO -MockWith {return $gpo} + $targetResource = Get-TargetResource @presentParams + $targetResource.Ensure | Should Be 'Absent' + } + } + #endregion + + + #region Function Test-TargetResource + Describe "$($Global:DSCResourceName)\Test-TargetResource" { + It 'Returns a "System.Boolean" object type' { + Mock -CommandName Import-Module -MockWith {} + Mock -CommandName Get-GPInheritance -MockWith {} + Mock -CommandName Get-GPO -MockWith {return $gpo} + $targetResource = Test-TargetResource @presentParams + $targetResource -is [System.Boolean] | Should Be $true + } + + It 'Passes when Ensure = Present and GPO Link found with correct properties' { + Mock -CommandName Import-Module -MockWith {} + Mock -CommandName Get-GPInheritance -MockWith {return $gpInheritanceCorrectProperties} + Mock -CommandName Get-GPO -MockWith {return $gpo} + Test-TargetResource @presentParams | Should Be $true + } + + It 'Fails when Ensure = Present and GPO Link found with incorrect properties' { + Mock -CommandName Import-Module -MockWith {} + Mock -CommandName Get-GPInheritance -MockWith {return $gpInheritanceIncorrectProperties} + Mock -CommandName Get-GPO -MockWith {return $gpo} + Test-TargetResource @presentParams | Should Be $false + } + + It 'Fails when Ensure = Present and GPO Link not found' { + Mock -CommandName Import-Module -MockWith {} + Mock -CommandName Get-GPInheritance -MockWith {} + Mock -CommandName Get-GPO -MockWith {return $gpo} + Test-TargetResource @presentParams | Should Be $false + } + + It 'Passes when Ensure = Absent and GPO Link not found' { + Mock -CommandName Import-Module -MockWith {} + Mock -CommandName Get-GPInheritance -MockWith {} + Mock -CommandName Get-GPO -MockWith {return $gpo} + Test-TargetResource @absentParams | Should Be $true + } + + It 'Failes when Ensure = Absent and GPO Link found' { + Mock -CommandName Import-Module -MockWith {} + Mock -CommandName Get-GPInheritance -MockWith {return $gpInheritanceCorrectProperties} + Mock -CommandName Get-GPO -MockWith {return $gpo} + Test-TargetResource @absentParams | Should Be $false + } + } + #endregion + + + #region Function Set-TargetResource + Describe "$($Global:DSCResourceName)\Set-TargetResource" { + It "Calls New-GPLink once when GPO Link not found" { + Mock -CommandName Import-Module -MockWith {} + Mock -CommandName Get-GPInheritance -MockWith {} + Mock -CommandName Get-GPO -MockWith {return $gpo} + Mock -CommandName New-GPLink -MockWith {} + Set-TargetResource @presentParams + Assert-MockCalled -CommandName New-GPLink -Times 1 -Exactly -Scope It + } + + It "Calls Set-GPLink once when GPO Link is found but the properties aren't correct" { + Mock -CommandName Import-Module -MockWith {} + Mock -CommandName Get-GPInheritance -MockWith {return $gpInheritanceIncorrectProperties} + Mock -CommandName Get-GPO -MockWith {return $gpo} + Mock -CommandName Set-GPLink -MockWith {} + Set-TargetResource @presentParams + Assert-MockCalled -CommandName Set-GPLink -Times 1 -Exactly -Scope It + } + + It "Calls Remove-GPLink once when Ensure = Absent and GPO Link found" { + Mock -CommandName Import-Module -MockWith {} + Mock -CommandName Get-GPInheritance -MockWith {return $gpInheritanceCorrectProperties} + Mock -CommandName Get-GPO -MockWith {return $gpo} + Mock -CommandName Remove-GPLink -MockWith {} + Set-TargetResource @absentParams + Assert-MockCalled -CommandName Remove-GPLink -Times 1 -Exactly -Scope It + } + } + #endregion + } + #endregion +} +finally +{ + #region FOOTER + Restore-TestEnvironment -TestEnvironment $TestEnvironment + #endregion +} diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000..7078d78 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,69 @@ +################################################################################ +# This is template for appveyor.yml +# Before using it in your repository, modify places marked with # TODO Modify +################################################################################ + +#---------------------------------# +# environment configuration # +#---------------------------------# +version: 1.0.{build}.0 +install: + - cinst -y pester + - git clone https://github.com/PowerShell/DscResource.Tests + - ps: Push-Location + - cd DscResource.Tests + - ps: Import-Module .\TestHelper.psm1 -force + - ps: Pop-Location + +#---------------------------------# +# build configuration # +#---------------------------------# + +build: false + +#---------------------------------# +# test configuration # +#---------------------------------# + +test_script: + - ps: | + $testResultsFile = ".\TestsResults.xml" + $res = Invoke-Pester -OutputFormat NUnitXml -OutputFile $testResultsFile -PassThru + (New-Object 'System.Net.WebClient').UploadFile("https://ci.appveyor.com/api/testresults/nunit/$($env:APPVEYOR_JOB_ID)", (Resolve-Path $testResultsFile)) + if ($res.FailedCount -gt 0) { + throw "$($res.FailedCount) tests failed." + } + +#---------------------------------# +# deployment configuration # +#---------------------------------# + +# scripts to run before deployment +deploy_script: + - ps: | + # Creating project artifact + $stagingDirectory = (Resolve-Path ..).Path + $manifest = Join-Path $pwd "xGroupPolicy.psd1" + (Get-Content $manifest -Raw).Replace("1.0.0.0", $env:APPVEYOR_BUILD_VERSION) | Out-File $manifest + $zipFilePath = Join-Path $stagingDirectory "$(Split-Path $pwd -Leaf).zip" + Add-Type -assemblyname System.IO.Compression.FileSystem + [System.IO.Compression.ZipFile]::CreateFromDirectory($pwd, $zipFilePath) + + # Creating NuGet package artifact + New-Nuspec -packageName $env:APPVEYOR_PROJECT_NAME -version $env:APPVEYOR_BUILD_VERSION -author "Microsoft" -owners "Microsoft" -licenseUrl "https://github.com/PowerShell/DscResources/blob/master/LICENSE" -projectUrl "https://github.com/$($env:APPVEYOR_REPO_NAME)" -packageDescription $env:APPVEYOR_PROJECT_NAME -tags "DesiredStateConfiguration DSC DSCResourceKit" -destinationPath . + nuget pack ".\$($env:APPVEYOR_PROJECT_NAME).nuspec" -outputdirectory . + $nuGetPackageName = $env:APPVEYOR_PROJECT_NAME + "." + $env:APPVEYOR_BUILD_VERSION + ".nupkg" + $nuGetPackagePath = (Get-ChildItem $nuGetPackageName).FullName + + @( + # You can add other artifacts here + $zipFilePath, + $nuGetPackagePath + ) | % { + Write-Host "Pushing package $_ as Appveyor artifact" + Push-AppveyorArtifact $_ + } + + + + diff --git a/xGroupPolicy.psd1 b/xGroupPolicy.psd1 new file mode 100644 index 0000000000000000000000000000000000000000..8f22b9ee1d57ca1d9185b995959ca619ce04d6e4 GIT binary patch literal 6672 zcmc(jYi|=r6o%(>rT&MN@_|q_p`k!YrAk;h36UU05TIWjJ9gdrR>x^T6@R_$`^@oS zcD%c(b5j*LyE`-I%zN%<=AXYe!q?%eun~&zDojH!oQF|3)z>(5!XyksUtecop^?7k z=W(XI?q2v94m3U$5F5or)W@55t476L$6gVfapOPfE1VKMQ}w5$E+*=;p#Wi&Bl_ZZ5S+c%s>fP|k%8 zO_b&BYtA&(kzUR;*VRap=t5tM@T=(fKh%n$8LBk*|zlky~cO+_Eh{& z;@Gan9>%X9G}_UAk7fPc733|U1A|%gGW~!lUv0RmKAG!=`LVo+I6()t)1Offy*2mE zc^rw?SoB3O1V?&bgn>r!$08i-yDOO{;y%)Epna>DW*Wu62U$Q5o_sEspdIH^gu1^c3!)PXeCk4LjPFIHcq$62} zwdA?Eoz_E6lv<6sJ=8CjJQFgrW{&$V>~NRTtYeGyWMUOjhUT#uSz$XIg*|1NBJ69% za?yom=i&EjdsJKW3-KkBRk_}tJY+Kbp12(A&#L4|QV4s=s=8RT@b7ukIweBda;rnH6>r{PNsB$lmzo zMATlh$m`@sv}W{W-f$)VHdnL_&At)0a#k$ocH}_TXVU!rtYd6Ndz}i)i4YFO<8qmi zrV~3N^6p*Wu18dlKJRzEe?@{#Mf^;%>_ksWHpC~bh7c>*kpFJ2ZnP6U@LaVUK3M3s zEtY!ZGX67Vr>W{HzTt7yWVK^;1G6Ycz04nF&(TtHx?1zs+;$f+tC$XwAFt_r6qKe)>nu7Z6vmZ~vIw!>e@Y2*kyQ;@6u+{tX-L6m3dWw9tHE_7q`=ACau zw|bI#ke#clp5xsZ)yeU!N>LwE`>~3o{uA6L@2Sqip6{?Ao=S(;oR_M+K)RRlu^jx( zO0WD}oO|+NYU@o9JoX@(ux5HcY z4}PlQ4uoocGb9`0*On~ZSgq*J64!cM)r$2}I1lHUM;_O*Pjtr5dc-*qMqe9@gyx04O&LVA+A zd``~2fG_d~E1hS$@8N!~{=8}RIoD}IWfn;HZiTq;mt${Q<*PSDaV%7WXqAq=#uRp8QPP-~MJ8{3)4;|Ifk+f|m zGDe2#v67ei%>n+>ixw&OG1hDTS3gJI`FWW^& Date: Tue, 23 Feb 2016 13:20:12 -0600 Subject: [PATCH 02/13] Update README.md Fixed duplicate configuration name under Examples. --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 8b80e10..93d3649 100644 --- a/README.md +++ b/README.md @@ -176,7 +176,7 @@ LinkEnforcedGPOByName In this example, we link a GPO by GUID to the Example OU and disable the link. We also leave off the domain part of the OU DN so it's generated automatically for us. ``` -configuration LinkEnforcedGPOByName +configuration LinkGPOByGuidAndDisable { Import-DscResource -Module xGPOLink @@ -192,5 +192,5 @@ configuration LinkEnforcedGPOByName } } } -LinkEnforcedGPOByName -``` \ No newline at end of file +LinkGPOByGuidAndDisable +``` From a857081a1776bc5ca5ddf8f5b29c494f8fcfffcf Mon Sep 17 00:00:00 2001 From: Cory Wood Date: Wed, 24 Feb 2016 10:45:57 -0600 Subject: [PATCH 03/13] Update MSFT_xGPOLink.psm1 Fixed typo for $newParams (was $setParams) in Set-TargetResource. --- DSCResources/MSFT_xGPOLink/MSFT_xGPOLink.psm1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/DSCResources/MSFT_xGPOLink/MSFT_xGPOLink.psm1 b/DSCResources/MSFT_xGPOLink/MSFT_xGPOLink.psm1 index d6ff65f..f5a77a4 100644 --- a/DSCResources/MSFT_xGPOLink/MSFT_xGPOLink.psm1 +++ b/DSCResources/MSFT_xGPOLink/MSFT_xGPOLink.psm1 @@ -122,11 +122,11 @@ function Set-TargetResource { $newParams += @{Guid = $gpo.Id} } else {$newParams += @{Guid = $Identity}} - if ($Domain) {$setParams += @{Domain = $Domain}} + if ($Domain) {$newParams += @{Domain = $Domain}} if ($Enforced) {$newParams += @{Enforced = $Enforced}} if ($LinkEnabled) {$newParams += @{LinkEnabled = $LinkEnabled}} if ($Order) {$newParams += @{Order = $Order}} - if ($Server) {$setParams += @{Server = $Server}} + if ($Server) {$newParams += @{Server = $Server}} Write-Verbose 'Creating GPO Link' New-GPLink @newParams } From 88c9c1e99c236f566e71ad076edb6311acab1472 Mon Sep 17 00:00:00 2001 From: Cory Wood Date: Wed, 24 Feb 2016 11:06:08 -0600 Subject: [PATCH 04/13] Update README.md Fixed typo in "Unblock inheritance on OU" example. --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 93d3649..250e97f 100644 --- a/README.md +++ b/README.md @@ -90,7 +90,7 @@ configuration UnblockInheritance xGPInheritance ExampleOU { Target = 'OU=Example,' - Ensure = 'Absent' + Ensure = 'Present' } } } From ffa153a4db0d94a4af43bb11eb4a60a856a9af06 Mon Sep 17 00:00:00 2001 From: Cory Wood Date: Tue, 26 Jul 2016 08:51:11 -0500 Subject: [PATCH 05/13] Create LICENSE.md --- LICENSE.md | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 LICENSE.md diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..4c5b450 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,21 @@ +The MIT License (MIT) + +Copyright (c) 2016 Cory Wood + +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. From 95613df70ab5f8d9face46e1669b63fd38a2d686 Mon Sep 17 00:00:00 2001 From: Cory Wood Date: Wed, 3 Aug 2016 09:34:35 -0500 Subject: [PATCH 06/13] Start of review From e0f6b25bb1da691cdef97e5fa0cd74ec1ec696f2 Mon Sep 17 00:00:00 2001 From: Cory Wood Date: Wed, 3 Aug 2016 09:57:45 -0500 Subject: [PATCH 07/13] Removed x from in front of resources. --- .../MSFT_xGPInheritance.psm1 | 137 --------- .../MSFT_xGPInheritance.schema.mof | 8 - .../MSFT_xGPOImport/MSFT_xGPOImport.psm1 | 104 ------- .../MSFT_xGPOImport.schema.mof | 12 - DSCResources/MSFT_xGPOLink/MSFT_xGPOLink.psm1 | 277 ------------------ .../MSFT_xGPOLink/MSFT_xGPOLink.schema.mof | 13 - README.md | 163 +---------- .../MSFT_xGPInheritance.Integration.tests.ps1 | 64 ---- .../MSFT_xGPInheritance.config.ps1 | 16 - .../MSFT_xGPOImport.Integration.tests.ps1 | 68 ----- Tests/Integration/MSFT_xGPOImport.config.ps1 | 25 -- .../MSFT_xGPOLink.Integration.tests.ps1 | 68 ----- Tests/Integration/MSFT_xGPOLink.config.ps1 | 23 -- Tests/Unit/MSFT_xGPInheritance.Tests.ps1 | 163 ----------- Tests/Unit/MSFT_xGPOImport.Tests.ps1 | 142 --------- Tests/Unit/MSFT_xGPOLink.Tests.ps1 | 199 ------------- appveyor.yml | 2 +- xGroupPolicy.psd1 | Bin 6672 -> 0 bytes 18 files changed, 12 insertions(+), 1472 deletions(-) delete mode 100644 DSCResources/MSFT_xGPInheritance/MSFT_xGPInheritance.psm1 delete mode 100644 DSCResources/MSFT_xGPInheritance/MSFT_xGPInheritance.schema.mof delete mode 100644 DSCResources/MSFT_xGPOImport/MSFT_xGPOImport.psm1 delete mode 100644 DSCResources/MSFT_xGPOImport/MSFT_xGPOImport.schema.mof delete mode 100644 DSCResources/MSFT_xGPOLink/MSFT_xGPOLink.psm1 delete mode 100644 DSCResources/MSFT_xGPOLink/MSFT_xGPOLink.schema.mof delete mode 100644 Tests/Integration/MSFT_xGPInheritance.Integration.tests.ps1 delete mode 100644 Tests/Integration/MSFT_xGPInheritance.config.ps1 delete mode 100644 Tests/Integration/MSFT_xGPOImport.Integration.tests.ps1 delete mode 100644 Tests/Integration/MSFT_xGPOImport.config.ps1 delete mode 100644 Tests/Integration/MSFT_xGPOLink.Integration.tests.ps1 delete mode 100644 Tests/Integration/MSFT_xGPOLink.config.ps1 delete mode 100644 Tests/Unit/MSFT_xGPInheritance.Tests.ps1 delete mode 100644 Tests/Unit/MSFT_xGPOImport.Tests.ps1 delete mode 100644 Tests/Unit/MSFT_xGPOLink.Tests.ps1 delete mode 100644 xGroupPolicy.psd1 diff --git a/DSCResources/MSFT_xGPInheritance/MSFT_xGPInheritance.psm1 b/DSCResources/MSFT_xGPInheritance/MSFT_xGPInheritance.psm1 deleted file mode 100644 index 8bafaef..0000000 --- a/DSCResources/MSFT_xGPInheritance/MSFT_xGPInheritance.psm1 +++ /dev/null @@ -1,137 +0,0 @@ -function Get-TargetResource -{ - [OutputType([Hashtable])] - param - ( - [parameter(Mandatory = $true)] - [string]$Target, - [string]$Domain, - [string]$Server, - [ValidateSet('Present','Absent')] - [string]$Ensure = 'Present' - ) - $Target = Test-TargetDN @PSBoundParameters - $targetResource = @{ - Target = $Target - Domain = $null - Server = $null - Ensure = $null - } - $params = @{Target = $Target} - if ($Domain) - { - $targetResource.Domain = $Domain - $params += @{Domain = $Domain} - } - if ($Server) - { - $targetResource.Server = $Server - $params += @{Server = $Server} - } - Import-Module GroupPolicy -Verbose:$false - Write-Verbose 'Getting Group Policy Inheritance' - $gpoInheritanceBlocked = (Get-GPInheritance @params).GpoInheritanceBlocked - if (!$gpoInheritanceBlocked) {$targetResource.Ensure = 'Present'} - else {$targetResource.Ensure = 'Absent'} - Write-Output $targetResource -} - -function Set-TargetResource -{ - param - ( - [parameter(Mandatory = $true)] - [string]$Target, - [string]$Domain, - [string]$Server, - [ValidateSet('Present','Absent')] - [string]$Ensure = 'Present' - ) - if ($Ensure -eq 'Present') - { - Write-Verbose 'Enabling Group Policy Inheritance' - $isBlocked = 'No' - } - else - { - Write-Verbose 'Disabling Group Policy Inheritance' - $isBlocked = 'Yes' - } - $Target = Test-TargetDN @PSBoundParameters - $params = @{ - Target = $Target - IsBlocked = $IsBlocked - } - if ($Domain) - { - $params += @{Domain = $Domain} - } - if ($Server) - { - $params += @{Server = $Server} - } - Import-Module GroupPolicy -Verbose:$false - $null = Set-GPInheritance @params -} - -function Test-TargetResource -{ -[OutputType([Boolean])] - param - ( - [parameter(Mandatory = $true)] - [string]$Target, - [string]$Domain, - [string]$Server, - [ValidateSet('Present','Absent')] - [string]$Ensure = 'Present' - ) - $targetResource = Get-TargetResource @PSBoundParameters - switch ($Ensure) - { - Present - { - if ($targetResource.Ensure -eq 'Present') {$true} - else {$false} - } - Absent - { - if ($targetResource.Ensure -eq 'Absent') {$true} - else {$false} - } - } -} - -function Test-TargetDN -{ - param - ( - [parameter(Mandatory = $true)] - [string]$Target, - [string]$Domain, - [string]$Server, - [ValidateSet('Present','Absent')] - [string]$Ensure = 'Present' - ) - $params = @{} - if ($Server) {$params += @{Server = $Server}} - Write-Verbose "Checking the Domain Distinguished Name is present on the Target Distinguished Name." - $domainDN = (Get-ADDomain @params).DistinguishedName - if ($Target -like "*$domainDN") - { - Write-Verbose "Target has full DN." - } - else - { - Write-Verbose "Adding the Domain Distinguished Name to the Target DN." - if ($Target.EndsWith(",")) - { - $Target = "$Target$domainDN" - } - else - { - $Target = "$Target,$domainDN" - } - } - $Target -} diff --git a/DSCResources/MSFT_xGPInheritance/MSFT_xGPInheritance.schema.mof b/DSCResources/MSFT_xGPInheritance/MSFT_xGPInheritance.schema.mof deleted file mode 100644 index 2a9aa12..0000000 --- a/DSCResources/MSFT_xGPInheritance/MSFT_xGPInheritance.schema.mof +++ /dev/null @@ -1,8 +0,0 @@ -[ClassVersion("1.0.0"), FriendlyName("xGPInheritance")] -class MSFT_xGPInheritance : OMI_BaseResource -{ - [Key] String Target; - [write] String Domain; - [write] String Server; - [write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] string Ensure; -}; diff --git a/DSCResources/MSFT_xGPOImport/MSFT_xGPOImport.psm1 b/DSCResources/MSFT_xGPOImport/MSFT_xGPOImport.psm1 deleted file mode 100644 index c7c50e4..0000000 --- a/DSCResources/MSFT_xGPOImport/MSFT_xGPOImport.psm1 +++ /dev/null @@ -1,104 +0,0 @@ -function Get-TargetResource -{ - [OutputType([Hashtable])] - param - ( - [parameter(Mandatory = $true)] - [string]$TargetName, - [parameter(Mandatory = $true)] - [string]$Path, - [parameter(Mandatory = $true)] - [string]$BackupIdentity, - [ValidateSet('Name','Guid')] - [string]$BackupIdentityType = 'Name', - [string]$Domain, - [string]$MigrationTable, - [string]$Server, - [ValidateSet('Present')] - [string]$Ensure = 'Present' - ) - Import-Module GroupPolicy -Verbose:$false - $params = @{ - Name = $TargetName - ErrorAction = 'SilentlyContinue' - } - if ($Domain) {$params += @{Domain = $Domain}} - if ($Server) {$params += @{Server = $Server}} - Write-Verbose 'Getting GPO' - $gpo = Get-GPO @params - $targetResource = @{ - TargetName = $TargetName - Path = $Path - BackupIdentity = $BackupIdentity - BackupIdentityType = $BackupIdentityType - Domain = $null - MigrationTable = $null - Server = $null - Ensure = 'Absent' - } - if ($MigrationTable) {$targetResource.MigrationTable = $MigrationTable} - if ($Server) {$targetResource.Server = $Server} - if ($gpo) - { - $targetResource.Domain = $gpo.DomainName - $targetResource.Ensure = 'Present' - } - $targetResource -} - -function Set-TargetResource -{ - param - ( - [parameter(Mandatory = $true)] - [string]$TargetName, - [parameter(Mandatory = $true)] - [string]$Path, - [parameter(Mandatory = $true)] - [string]$BackupIdentity, - [ValidateSet('Name','Guid')] - [string]$BackupIdentityType = 'Name', - [string]$Domain, - [string]$MigrationTable, - [string]$Server, - [ValidateSet('Present')] - [string]$Ensure = 'Present' - ) - Import-Module GroupPolicy -Verbose:$false - $params = @{ - TargetName = $TargetName - Path = $Path - CreateIfNeeded = $true - } - if ($BackupIdentityType -eq 'Name') {$params += @{BackupGpoName = $BackupIdentity}} - else {$params += @{BackupId = $BackupIdentity}} - if ($Domain) {$params += @{Domain = $Domain}} - if ($MigrationTable) {$params += @{MigrationTable = $MigrationTable}} - if ($Server) {$params += @{Server = $Server}} - Write-Verbose 'Importing GPO' - $null = Import-GPO @params -} - -function Test-TargetResource -{ -[OutputType([Boolean])] - param - ( - [parameter(Mandatory = $true)] - [string]$TargetName, - [parameter(Mandatory = $true)] - [string]$Path, - [parameter(Mandatory = $true)] - [string]$BackupIdentity, - [ValidateSet('Name','Guid')] - [string]$BackupIdentityType = 'Name', - [string]$Domain, - [string]$MigrationTable, - [string]$Server, - [ValidateSet('Present')] - [string]$Ensure = 'Present' - ) - $targetResource = Get-TargetResource @PSBoundParameters - if ($targetResource.Ensure -eq 'Present') {$true} - else {$false} -} diff --git a/DSCResources/MSFT_xGPOImport/MSFT_xGPOImport.schema.mof b/DSCResources/MSFT_xGPOImport/MSFT_xGPOImport.schema.mof deleted file mode 100644 index ab0e4af..0000000 --- a/DSCResources/MSFT_xGPOImport/MSFT_xGPOImport.schema.mof +++ /dev/null @@ -1,12 +0,0 @@ -[ClassVersion("1.0.0"), FriendlyName("xGPOImport")] -class MSFT_xGPOImport : OMI_BaseResource -{ - [Key] String TargetName; - [required] String Path; - [required] String BackupIdentity; - [write,ValueMap{"Name", "Guid"},Values{"Name", "Guid"}] string BackupIdentityType; - [write] String Domain; - [write] String MigrationTable; - [write] String Server; - [write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] string Ensure; -}; diff --git a/DSCResources/MSFT_xGPOLink/MSFT_xGPOLink.psm1 b/DSCResources/MSFT_xGPOLink/MSFT_xGPOLink.psm1 deleted file mode 100644 index f5a77a4..0000000 --- a/DSCResources/MSFT_xGPOLink/MSFT_xGPOLink.psm1 +++ /dev/null @@ -1,277 +0,0 @@ -function Get-TargetResource { - [OutputType([Hashtable])] - param - ( - [parameter(Mandatory = $true)] - [string]$Identity, - [ValidateSet('Name','Guid')] - [string]$IdentityType = 'Name', - [parameter(Mandatory = $true)] - [string]$Target, - [string]$Domain, - [ValidateSet('Yes','No')] - [string]$Enforced, - [ValidateSet('Yes','No')] - [string]$LinkEnabled, - [int16]$Order, - [string]$Server, - [ValidateSet('Present','Absent')] - [string]$Ensure = 'Present' - ) - $target = Test-TargetDN @PSBoundParameters - $gpInheritanceparams = @{ - Target = $target - } - if ($Server) {$gpInheritanceparams += @{Server = $Server}} - if ($Domain) {$gpInheritanceparams += @{Domain = $Domain}} - Import-Module GroupPolicy -Verbose:$false - Write-Verbose 'Getting GPO Links' - $gpoLinks = (Get-GPInheritance @gpInheritanceparams).GpoLinks - $gpo = Get-GpoInfo @PSBoundParameters - $targetResource = @{ - Identity = $Identity - IdentityType = $IdentityType - Target = $Target - Domain = $null - Enforced = $null - LinkEnabled = $null - Order = $null - Server = $Server - Ensure = 'Absent' - } - if ($gpo) - { - # Using the GpoId attribute of the GPO Links instead of the - # Name attribute because the Name attribute may take a while - # to replicate to all DCs if the GPO was recently created. - $targetLink = $gpoLinks | where {$_.GpoId -eq $gpo.Id} - if ($targetLink) - { - if ($targetLink.Enabled) {$targetResource.LinkEnabled = 'Yes'} - else {$targetResource.LinkEnabled = 'No'} - if ($targetLink.Enforced) {$targetResource.Enforced = 'Yes'} - else {$targetResource.Enforced = 'No'} - $targetResource.Order = $targetLink.Order - $targetResource.Ensure = 'Present' - } - $targetResource.Domain = $gpo.DomainName - } - $targetResource -} - -function Set-TargetResource { - param - ( - [parameter(Mandatory = $true)] - [string]$Identity, - [ValidateSet('Name','Guid')] - [string]$IdentityType = 'Name', - [parameter(Mandatory = $true)] - [string]$Target, - [string]$Domain, - [ValidateSet('Yes','No')] - [string]$Enforced, - [ValidateSet('Yes','No')] - [string]$LinkEnabled, - [int16]$Order, - [string]$Server, - [ValidateSet('Present','Absent')] - [string]$Ensure = 'Present' - ) - Import-Module GroupPolicy -Verbose:$false - $targetResource = Get-TargetResource @PSBoundParameters - $gpo = Get-GpoInfo @PSBoundParameters - if ($Ensure -eq 'Present') - { - if ($targetResource.Ensure -eq 'Present') - { - $setParams = @{Target = $targetResource.Target} - if ($IdentityType -eq 'Name') - { - # Using the GpoId attribute of the GPO Links instead of the - # Name attribute because the Name attribute may take a while - # to replicate to all DCs if the GPO was recently created. - $setParams += @{Guid = $gpo.Id} - } - else {$setParams += @{Guid = $Identity}} - if ($Domain) {$setParams += @{Domain = $Domain}} - if ($Enforced -and $targetResource.Enforced -ne $Enforced) - { - $setParams += @{Enforced = $Enforced} - } - if ($LinkEnabled -and $targetResource.LinkEnabled -ne $LinkEnabled) - { - $setParams += @{LinkEnabled = $LinkEnabled} - } - if ($Order -and $targetResource.Order -ne $Order) - { - $setParams += @{Order = $Order} - } - if ($Server) {$setParams += @{Server = $Server}} - Write-Verbose 'Updating GPO Link' - Set-GPLink @setParams - } - else - { - $newParams = @{Target = $targetResource.Target} - if ($IdentityType -eq 'Name') - { - # Using the GpoId attribute of the GPO Links instead of the - # Name attribute because the Name attribute may take a while - # to replicate to all DCs if the GPO was recently created. - $newParams += @{Guid = $gpo.Id} - } - else {$newParams += @{Guid = $Identity}} - if ($Domain) {$newParams += @{Domain = $Domain}} - if ($Enforced) {$newParams += @{Enforced = $Enforced}} - if ($LinkEnabled) {$newParams += @{LinkEnabled = $LinkEnabled}} - if ($Order) {$newParams += @{Order = $Order}} - if ($Server) {$newParams += @{Server = $Server}} - Write-Verbose 'Creating GPO Link' - New-GPLink @newParams - } - } - else - { - $removeParams = @{Target = $targetResource.Target} - if ($IdentityType -eq 'Name') - { - # Using the GpoId attribute of the GPO Links instead of the - # Name attribute because the Name attribute may take a while - # to replicate to all DCs if the GPO was recently created. - $removeParams += @{Guid = $gpo.Id} - } - else {$removeParams += @{Guid = $Identity}} - if ($Domain) {$removeParams += @{Domain = $Domain}} - if ($Server) {$removeParams += @{Server = $Server}} - Write-Verbose 'Removing GPO Link' - Remove-GPLink @removeParams - } -} - -function Test-TargetResource { -[OutputType([Boolean])] - param - ( - [parameter(Mandatory = $true)] - [string]$Identity, - [ValidateSet('Name','Guid')] - [string]$IdentityType = 'Name', - [parameter(Mandatory = $true)] - [string]$Target, - [string]$Domain, - [ValidateSet('Yes','No')] - [string]$Enforced, - [ValidateSet('Yes','No')] - [string]$LinkEnabled, - [int16]$Order, - [string]$Server, - [ValidateSet('Present','Absent')] - [string]$Ensure = 'Present' - ) - $targetResource = Get-TargetResource @PSBoundParameters - $targetResourceInCompliance = $true - if ($Ensure -eq 'Present') - { - if ($targetResource.Ensure -eq 'Present') - { - if ($Enforced -and $targetResource.Enforced -ne $Enforced) - { - $targetResourceInCompliance = $false - } - if ($LinkEnabled -and $targetResource.LinkEnabled -ne $LinkEnabled) - { - $targetResourceInCompliance = $false - } - if ($Order -and $targetResource.Order -ne $Order) - { - $targetResourceInCompliance = $false - } - } - else {$targetResourceInCompliance = $false} - } - elseif ($targetResource.Ensure -eq 'Present') - { - $targetResourceInCompliance = $false - } - $targetResourceInCompliance -} - -function Test-TargetDN -{ - param - ( - [parameter(Mandatory = $true)] - [string]$Identity, - [ValidateSet('Name','Guid')] - [string]$IdentityType = 'Name', - [parameter(Mandatory = $true)] - [string]$Target, - [string]$Domain, - [ValidateSet('Yes','No')] - [string]$Enforced, - [ValidateSet('Yes','No')] - [string]$LinkEnabled, - [int16]$Order, - [string]$Server, - [ValidateSet('Present','Absent')] - [string]$Ensure = 'Present' - ) - $params = @{} - if ($Server) {$params += @{Server = $Server}} - Write-Verbose "Checking the Domain Distinguished Name is present on the Target Distinguished Name." - $domainDN = (Get-ADDomain @params).DistinguishedName - if ($Target -like "*$domainDN") - { - Write-Verbose "Target has full DN." - } - else - { - Write-Verbose "Adding the Domain Distinguished Name to the Target DN." - if ($Target.EndsWith(",")) - { - $Target = "$Target$domainDN" - } - else - { - $Target = "$Target,$domainDN" - } - } - $Target -} - -function Get-GpoInfo -{ - param - ( - [parameter(Mandatory = $true)] - [string]$Identity, - [ValidateSet('Name','Guid')] - [string]$IdentityType = 'Name', - [parameter(Mandatory = $true)] - [string]$Target, - [string]$Domain, - [ValidateSet('Yes','No')] - [string]$Enforced, - [ValidateSet('Yes','No')] - [string]$LinkEnabled, - [int16]$Order, - [string]$Server, - [ValidateSet('Present','Absent')] - [string]$Ensure = 'Present' - ) - $gpoParams = @{} - if ($Server) - { - $gpoParams += @{Server = $Server} - } - if ($Domain) - { - $gpoParams += @{Domain = $Domain} - } - if ($IdentityType -eq 'Name') {$gpoParams += @{Name = $Identity}} - else {$gpoParams += @{Guid = $Identity}} - Import-Module GroupPolicy -Verbose:$false - Write-Verbose 'Getting GPO' - Get-GPO @gpoParams -} diff --git a/DSCResources/MSFT_xGPOLink/MSFT_xGPOLink.schema.mof b/DSCResources/MSFT_xGPOLink/MSFT_xGPOLink.schema.mof deleted file mode 100644 index 975773e..0000000 --- a/DSCResources/MSFT_xGPOLink/MSFT_xGPOLink.schema.mof +++ /dev/null @@ -1,13 +0,0 @@ -[ClassVersion("1.0.0"), FriendlyName("xGPOLink")] -class MSFT_xGPOLink : OMI_BaseResource -{ - [Key] String Identity; - [Write,ValueMap{"Name", "Guid"},Values{"Name", "Guid"}] String IdentityType; - [Key] String Target; - [Write] String Domain; - [Write,ValueMap{"Yes", "No"},Values{"Yes", "No"}] String Enforced; - [Write,ValueMap{"Yes", "No"},Values{"Yes", "No"}] String LinkEnabled; - [Write] Sint16 Order; - [Write] String Server; - [Write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] String Ensure; -}; diff --git a/README.md b/README.md index 250e97f..ae44cf7 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,26 @@ {{AppVeyor build status badge for master branch}} -# xGroupPolicy +# GroupPolicyDsc -The **xGroupPolicy** module contains DSC resources for configuring Group Policy. +The **GroupPolicyDsc** module contains DSC resources for configuring Group Policy. ## Contributing Please check out common DSC Resources [contributing guidelines](https://github.com/PowerShell/DscResource.Kit/blob/master/CONTRIBUTING.md). ## Resources -* **xGPInheritance** blocks or unblocks inheritance for a specified domain or organizational unit (OU). -* **xGPOImport** imports the Group Policy settings from a backed-up GPO into a new GPO. It won't import settings into an existing GPO. -* **xGPOLink** links a GPO to a site, domain, or organizational unit (OU). +* **GPInheritance** blocks or unblocks inheritance for a specified domain or organizational unit (OU). +* **GPOImport** imports the Group Policy settings from a backed-up GPO into a new GPO. It won't import settings into an existing GPO. +* **GPOLink** links a GPO to a site, domain, or organizational unit (OU). -### xGPInheritance +### GPInheritance * **Target**: Specifies the domain or the OU for which to block or unblock inheritance by its LDAP distinguished name. You can also leave off the domain part of the distinguished name and it will be generated automatically. See the example below. * **Domain**: Optional. Specifies the domain to run against. * **Server**: Optional. Specifies the name of the domain controller that this resource contacts to complete the operation. You can specify either the fully qualified domain name (FQDN) or the host name. * **Ensure**: Whether inheritance should be blocked (Absent) or unblocked (Present). Defaults to Present. -### xGPOImport +### GPOImport * **TargetName**: Specifies the display name of the GPO into which the settings are to be imported. * **Path**: Specifies the path to the backup directory. @@ -31,7 +31,7 @@ Please check out common DSC Resources [contributing guidelines](https://github.c * **Server**: Optional. Specifies the name of the domain controller that this resource contacts to complete the operation. You can specify either the fully qualified domain name (FQDN) or the host name. * **Ensure**: Must be Present. Defaults to Present. -### xGPOLink +### GPOLink * **Identity**: Specifies the GPO to link by its display name or GUID. * **IdentityType**: Specifies the type of the Identity (Name or Guid). Defaults to Name. @@ -50,147 +50,6 @@ Please check out common DSC Resources [contributing guidelines](https://github.c ### 1.0.0.0 * Initial release with the following resources: - * xGPInheritance - * xGPOImport - * xGPOLink - -## Examples -### Block inheritance on OU - -In this example, we block inheritance on the Example OU. - -``` -configuration BlockInheritance -{ - Import-DscResource -Module xGPInheritance - - Node $AllNodes.NodeName - { - xGPInheritance ExampleOU - { - Target = 'OU=Example,DC=testdomain,DC=local' - Ensure = 'Absent' - } - } -} -BlockInheritance -``` - -### Unblock inheritance on OU - -In this example, we unblock inheritance on the Example OU. We also leave off the domain part of the OU DN so it's generated automatically for us. - -``` -configuration UnblockInheritance -{ - Import-DscResource -Module xGPInheritance - - Node $AllNodes.NodeName - { - xGPInheritance ExampleOU - { - Target = 'OU=Example,' - Ensure = 'Present' - } - } -} -UnblockInheritance -``` - -### Import Group Policy Settings by Name with Migration Table - -In this example, we import group policy settings into the Example GPO by specifying the backup name. We also use a migration table. - -``` -configuration ImportByName -{ - Import-DscResource -Module xGPOImport - - Node $AllNodes.NodeName - { - xGPOImport ExampleOU - { - TargetName = 'Example' - Path = "C:\GPO Backups\Example" - BackupIdentity = 'Example' - BackupIdentityType = 'Name' - MigrationTable = 'C:\GPO Backups\ExampleMigTable.mitable' - Ensure = 'Present' - } - } -} -ImportByName -``` - -### Import Group Policy Settings by GUID - -In this example, we import group policy settings into the Example GPO by specifying the backup GUID. - -``` -configuration ImportByGuid -{ - Import-DscResource -Module xGPOImport - - Node $AllNodes.NodeName - { - xGPOImport ExampleOU - { - TargetName = 'Example' - Path = "C:\GPO Backups\Example" - BackupIdentity = '7b230cb8-67fc-433d-812f-c93b53310dcf' - BackupIdentityType = 'Guid' - Ensure = 'Present' - } - } -} -ImportByGuid -``` - -### Link and Enforce GPO by Name. - -In this example, we link the Example GPO by name to the Example OU and enforce the link. We also change the link order to 1. - -``` -configuration LinkEnforcedGPOByName -{ - Import-DscResource -Module xGPOLink - - Node $AllNodes.NodeName - { - xGPOLink ExampleOU - { - Identity = 'Example' - IdentityType = 'Name' - Target = 'OU=Example,DC=testdomain,DC=local' - Enforced = 'Yes' - Order = 1 - Ensure = 'Present' - } - } -} -LinkEnforcedGPOByName -``` - -### Link GPO by GUID and Disable Link. - -In this example, we link a GPO by GUID to the Example OU and disable the link. We also leave off the domain part of the OU DN so it's generated automatically for us. - -``` -configuration LinkGPOByGuidAndDisable -{ - Import-DscResource -Module xGPOLink - - Node $AllNodes.NodeName - { - xGPOLink ExampleOU - { - Identity = '9b74f3ec-a20e-4567-a1cd-f0b13a339037' - IdentityType = 'Guid' - Target = 'OU=Example,' - LinkEnabled = 'No' - Ensure = 'Present' - } - } -} -LinkGPOByGuidAndDisable -``` + * GPInheritance + * GPOImport + * GPOLink diff --git a/Tests/Integration/MSFT_xGPInheritance.Integration.tests.ps1 b/Tests/Integration/MSFT_xGPInheritance.Integration.tests.ps1 deleted file mode 100644 index f7217d6..0000000 --- a/Tests/Integration/MSFT_xGPInheritance.Integration.tests.ps1 +++ /dev/null @@ -1,64 +0,0 @@ -$Global:DSCModuleName = 'xGroupPolicy' -$Global:DSCResourceName = 'MSFT_xGPInheritance' -# /TODO - -#region HEADER -[String] $moduleRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $Script:MyInvocation.MyCommand.Path)) -if ( (-not (Test-Path -Path (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests'))) -or ` - (-not (Test-Path -Path (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1'))) ) -{ - & git @('clone','https://github.com/PowerShell/DscResource.Tests.git',(Join-Path -Path $moduleRoot -ChildPath '\DSCResource.Tests\')) -} -else -{ - & git @('-C',(Join-Path -Path $moduleRoot -ChildPath '\DSCResource.Tests\'),'pull') -} -Import-Module (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1') -Force -$TestEnvironment = Initialize-TestEnvironment ` - -DSCModuleName $Global:DSCModuleName ` - -DSCResourceName $Global:DSCResourceName ` - -TestType Integration -#endregion - -# TODO: Other Init Code Goes Here... - -# Using try/finally to always cleanup even if something awful happens. -try -{ - #region Integration Tests - $ConfigFile = Join-Path -Path $PSScriptRoot -ChildPath "$($Global:DSCResourceName).config.ps1" - . $ConfigFile - - Describe "$($Global:DSCResourceName)_Integration" { - #region DEFAULT TESTS - It 'Should compile without throwing' { - { - Invoke-Expression -Command "$($Global:DSCResourceName)_Config -OutputPath `$TestEnvironment.WorkingFolder" - Start-DscConfiguration -Path $TestEnvironment.WorkingFolder ` - -ComputerName localhost -Wait -Verbose -Force - } | Should not throw - } - - It 'should be able to call Get-DscConfiguration without throwing' { - { Get-DscConfiguration -Verbose -ErrorAction Stop } | Should Not throw - } - #endregion - - It 'Should have set the resource and all the parameters should match' { - $current = Get-DscConfiguration - $current.Target | Should Be $GPInheritance.Target - $current.Server | Should Be $GPInheritance.Server - $current.Ensure | Should Be $GPInheritance.Ensure - } - } - #endregion - -} -finally -{ - #region FOOTER - Restore-TestEnvironment -TestEnvironment $TestEnvironment - #endregion - - # TODO: Other Optional Cleanup Code Goes Here... -} diff --git a/Tests/Integration/MSFT_xGPInheritance.config.ps1 b/Tests/Integration/MSFT_xGPInheritance.config.ps1 deleted file mode 100644 index b05077c..0000000 --- a/Tests/Integration/MSFT_xGPInheritance.config.ps1 +++ /dev/null @@ -1,16 +0,0 @@ -$ou = 'OU=Test OU,DC=testdomain,DC=local' -$GPInheritance = @{ - Target = $ou - Server = 'localhost' - Ensure = 'Present' -} -configuration 'MSFT_xGPInheritance_config' { - Import-DscResource -Name 'MSFT_xGPInheritance' - node localhost { - xGPInheritance Integration_Test { - Target = $GPInheritance.Target - Server = $GPInheritance.Server - Ensure = $GPInheritance.Ensure - } - } -} \ No newline at end of file diff --git a/Tests/Integration/MSFT_xGPOImport.Integration.tests.ps1 b/Tests/Integration/MSFT_xGPOImport.Integration.tests.ps1 deleted file mode 100644 index 6903d47..0000000 --- a/Tests/Integration/MSFT_xGPOImport.Integration.tests.ps1 +++ /dev/null @@ -1,68 +0,0 @@ -$Global:DSCModuleName = 'xGroupPolicy' -$Global:DSCResourceName = 'MSFT_xGPOImport' -# /TODO - -#region HEADER -[String] $moduleRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $Script:MyInvocation.MyCommand.Path)) -if ( (-not (Test-Path -Path (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests'))) -or ` - (-not (Test-Path -Path (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1'))) ) -{ - & git @('clone','https://github.com/PowerShell/DscResource.Tests.git',(Join-Path -Path $moduleRoot -ChildPath '\DSCResource.Tests\')) -} -else -{ - & git @('-C',(Join-Path -Path $moduleRoot -ChildPath '\DSCResource.Tests\'),'pull') -} -Import-Module (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1') -Force -$TestEnvironment = Initialize-TestEnvironment ` - -DSCModuleName $Global:DSCModuleName ` - -DSCResourceName $Global:DSCResourceName ` - -TestType Integration -#endregion - -# TODO: Other Init Code Goes Here... - -# Using try/finally to always cleanup even if something awful happens. -try -{ - #region Integration Tests - $ConfigFile = Join-Path -Path $PSScriptRoot -ChildPath "$($Global:DSCResourceName).config.ps1" - . $ConfigFile - - Describe "$($Global:DSCResourceName)_Integration" { - #region DEFAULT TESTS - It 'Should compile without throwing' { - { - Invoke-Expression -Command "$($Global:DSCResourceName)_Config -OutputPath `$TestEnvironment.WorkingFolder" - Start-DscConfiguration -Path $TestEnvironment.WorkingFolder ` - -ComputerName localhost -Wait -Verbose -Force - } | Should not throw - } - - It 'should be able to call Get-DscConfiguration without throwing' { - { Get-DscConfiguration -Verbose -ErrorAction Stop } | Should Not throw - } - #endregion - - It 'Should have set the resource and all the parameters should match' { - $current = Get-DscConfiguration - $current.TargetName | Should Be $GPO.TargetName - $current.Path | Should Be $GPO.Path - $current.BackupIdentity | Should Be $GPO.BackupIdentity - $current.BackupIdentityType | Should Be $GPO.BackupIdentityType - $current.Domain | Should Be $GPO.Domain - $current.MigrationTable | Should Be $GPO.MigrationTable - $current.Server | Should Be $GPO.Server - } - } - #endregion - -} -finally -{ - #region FOOTER - Restore-TestEnvironment -TestEnvironment $TestEnvironment - #endregion - - # TODO: Other Optional Cleanup Code Goes Here... -} diff --git a/Tests/Integration/MSFT_xGPOImport.config.ps1 b/Tests/Integration/MSFT_xGPOImport.config.ps1 deleted file mode 100644 index 0b9068b..0000000 --- a/Tests/Integration/MSFT_xGPOImport.config.ps1 +++ /dev/null @@ -1,25 +0,0 @@ -$gpoName = 'Test GPO' -$domainName = 'testdomain.local' -$GPO = @{ - TargetName = $gpoName - Path = "C:\Test Path\GPO Backups\$gpoName" - BackupIdentity = $gpoName - BackupIdentityType = 'Name' - Domain = $domainName - MigrationTable = 'C:\Test Path\GPO Backups\MigTable.mitable' - Server = 'localhost' -} -configuration 'MSFT_xGPOImport_config' { - Import-DscResource -Name 'MSFT_xGPOImport' - node localhost { - xGPOImport Integration_Test { - TargetName = $GPO.TargetName - Path = $GPO.Path - BackupIdentity = $GPO.BackupIdentity - BackupIdentityType = $GPO.BackupIdentityType - Domain = $GPO.Domain - MigrationTable = $GPO.MigrationTable - Server = $GPO.Server - } - } -} \ No newline at end of file diff --git a/Tests/Integration/MSFT_xGPOLink.Integration.tests.ps1 b/Tests/Integration/MSFT_xGPOLink.Integration.tests.ps1 deleted file mode 100644 index 740a783..0000000 --- a/Tests/Integration/MSFT_xGPOLink.Integration.tests.ps1 +++ /dev/null @@ -1,68 +0,0 @@ -$Global:DSCModuleName = 'xGroupPolicy' -$Global:DSCResourceName = 'MSFT_xGPOLink' -# /TODO - -#region HEADER -[String] $moduleRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $Script:MyInvocation.MyCommand.Path)) -if ( (-not (Test-Path -Path (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests'))) -or ` - (-not (Test-Path -Path (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1'))) ) -{ - & git @('clone','https://github.com/PowerShell/DscResource.Tests.git',(Join-Path -Path $moduleRoot -ChildPath '\DSCResource.Tests\')) -} -else -{ - & git @('-C',(Join-Path -Path $moduleRoot -ChildPath '\DSCResource.Tests\'),'pull') -} -Import-Module (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1') -Force -$TestEnvironment = Initialize-TestEnvironment ` - -DSCModuleName $Global:DSCModuleName ` - -DSCResourceName $Global:DSCResourceName ` - -TestType Integration -#endregion - -# TODO: Other Init Code Goes Here... - -# Using try/finally to always cleanup even if something awful happens. -try -{ - #region Integration Tests - $ConfigFile = Join-Path -Path $PSScriptRoot -ChildPath "$($Global:DSCResourceName).config.ps1" - . $ConfigFile - - Describe "$($Global:DSCResourceName)_Integration" { - #region DEFAULT TESTS - It 'Should compile without throwing' { - { - Invoke-Expression -Command "$($Global:DSCResourceName)_Config -OutputPath `$TestEnvironment.WorkingFolder" - Start-DscConfiguration -Path $TestEnvironment.WorkingFolder ` - -ComputerName localhost -Wait -Verbose -Force - } | Should not throw - } - - It 'should be able to call Get-DscConfiguration without throwing' { - { Get-DscConfiguration -Verbose -ErrorAction Stop } | Should Not throw - } - #endregion - - It 'Should have set the resource and all the parameters should match' { - $current = Get-DscConfiguration - $current.Identity | Should Be $GPOLink.Identity - $current.IdentityType | Should Be $GPOLink.IdentityType - $current.Target | Should Be $GPOLink.Target - $current.Enforced | Should Be $GPOLink.Enforced - $current.LinkEnabled | Should Be $GPOLink.LinkEnabled - $current.Order | Should Be $GPOLink.Order - $current.Ensure | Should Be $GPOLink.Ensure - } - } - #endregion - -} -finally -{ - #region FOOTER - Restore-TestEnvironment -TestEnvironment $TestEnvironment - #endregion - - # TODO: Other Optional Cleanup Code Goes Here... -} diff --git a/Tests/Integration/MSFT_xGPOLink.config.ps1 b/Tests/Integration/MSFT_xGPOLink.config.ps1 deleted file mode 100644 index cf4892b..0000000 --- a/Tests/Integration/MSFT_xGPOLink.config.ps1 +++ /dev/null @@ -1,23 +0,0 @@ -$GPOLink = @{ - Identity = 'Test GPO' - IdentityType = 'Name' - Target = 'OU=Test OU,DC=testdomain,DC=local' - Enforced = 'No' - LinkEnabled = 'Yes' - Order = 1 - Ensure = 'Present' -} -configuration 'MSFT_xGPOLink_config' { - Import-DscResource -Name 'MSFT_xGPOLink' - node localhost { - xGPOLink Integration_Test { - Identity = $GPOLink.Identity - IdentityType = $GPOLink.IdentityType - Target = $GPOLink.Target - Enforced = $GPOLink.Enforced - LinkEnabled = $GPOLink.LinkEnabled - Order = $GPOLink.Order - Ensure = $GPOLink.Ensure - } - } -} \ No newline at end of file diff --git a/Tests/Unit/MSFT_xGPInheritance.Tests.ps1 b/Tests/Unit/MSFT_xGPInheritance.Tests.ps1 deleted file mode 100644 index 41bc4c4..0000000 --- a/Tests/Unit/MSFT_xGPInheritance.Tests.ps1 +++ /dev/null @@ -1,163 +0,0 @@ -$Global:DSCModuleName = 'xGroupPolicy' -$Global:DSCResourceName = 'MSFT_xGPInheritance' - -#region HEADER -[String] $moduleRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $Script:MyInvocation.MyCommand.Path)) -if ( (-not (Test-Path -Path (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests'))) -or ` - (-not (Test-Path -Path (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1'))) ) -{ - & git @('clone','https://github.com/PowerShell/DscResource.Tests.git',(Join-Path -Path $moduleRoot -ChildPath '\DSCResource.Tests\')) -} -else -{ - & git @('-C',(Join-Path -Path $moduleRoot -ChildPath '\DSCResource.Tests\'),'pull') -} -Import-Module (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1') -Force -$TestEnvironment = Initialize-TestEnvironment ` - -DSCModuleName $Global:DSCModuleName ` - -DSCResourceName $Global:DSCResourceName ` - -TestType Unit -#endregion - -# Begin Testing -try -{ - - #region Pester Tests - - # The InModuleScope command allows you to perform white-box unit testing on the internal - # (non-exported) code of a Script Module. - InModuleScope $Global:DSCResourceName { - - #region Pester Test Initialization - function Get-ADDomain {} - function Get-GPInheritance {} - function Set-GPInheritance {} - $rootDSE = 'DC=testdomain,DC=local' - $ou = 'OU=Test OU' - $presentParams = @{ - Target = "$ou,$rootDSE" - Server = 'localhost' - Ensure = 'Present' - } - $presentPartialOUParams = @{ - Target = "$ou," - Server = 'localhost' - Ensure = 'Present' - } - $absentParams = @{ - Target = "$ou,$rootDSE" - Server = 'localhost' - Ensure = 'Absent' - } - $fakeADDomain = @{DistinguishedName = $rootDSE} - $fakeGPInheritanceNotBlocked = @{GpoInheritanceBlocked = $false} - $fakeGPInheritanceBlocked = @{GpoInheritanceBlocked = $true} - #endregion - - - #region Function Get-TargetResource - Describe "$($Global:DSCResourceName)\Get-TargetResource" { - It 'Returns a "System.Collections.Hashtable" object type' { - Mock -CommandName Get-ADDomain -MockWith {$fakeADDomain} - Mock -CommandName Import-Module -MockWith {} - Mock -CommandName Get-GPInheritance -MockWith {$fakeGPInheritanceNotBlocked} - $targetResource = Get-TargetResource @presentParams - $targetResource -is [System.Collections.Hashtable] | Should Be $true - } - - It "Returns Ensure = Present when group policy inheritance is not blocked on the Target" { - Mock -CommandName Get-ADDomain -MockWith {$fakeADDomain} - Mock -CommandName Import-Module -MockWith {} - Mock -CommandName Get-GPInheritance -MockWith {$fakeGPInheritanceNotBlocked} - $targetResource = Get-TargetResource @presentParams - $targetResource.Ensure | Should Be 'Present' - } - - It "Returns Ensure = Absent when group policy inheritance is blocked on the Target" { - Mock -CommandName Get-ADDomain -MockWith {$fakeADDomain} - Mock -CommandName Import-Module -MockWith {} - Mock -CommandName Get-GPInheritance -MockWith {$fakeGPInheritanceBlocked} - $targetResource = Get-TargetResource @presentParams - $targetResource.Ensure | Should Be 'Absent' - } - } - #endregion - - - #region Function Test-TargetResource - Describe "$($Global:DSCResourceName)\Test-TargetResource" { - It 'Returns a "System.Boolean" object type' { - Mock -CommandName Get-ADDomain -MockWith {$fakeADDomain} - Mock -CommandName Import-Module -MockWith {} - Mock -CommandName Get-GPInheritance -MockWith {$fakeGPInheritanceNotBlocked} - $targetResource = Test-TargetResource @presentParams - $targetResource -is [System.Boolean] | Should Be $true - } - - It 'Passes when Ensure = Present and group policy inheritance is not blocked on the Target' { - Mock -CommandName Get-ADDomain -MockWith {$fakeADDomain} - Mock -CommandName Import-Module -MockWith {} - Mock -CommandName Get-GPInheritance -MockWith {$fakeGPInheritanceNotBlocked} - Test-TargetResource @presentParams | Should Be $true - } - - It 'Fails when Ensure = Present and group policy inheritance is blocked on the Target' { - Mock -CommandName Get-ADDomain -MockWith {$fakeADDomain} - Mock -CommandName Import-Module -MockWith {} - Mock -CommandName Get-GPInheritance -MockWith {$fakeGPInheritanceBlocked} - Test-TargetResource @presentParams | Should Be $false - } - - It 'Passes when Ensure = Absent and group policy inheritance is blocked on the Target' { - Mock -CommandName Get-ADDomain -MockWith {$fakeADDomain} - Mock -CommandName Import-Module -MockWith {} - Mock -CommandName Get-GPInheritance -MockWith {$fakeGPInheritanceBlocked} - Test-TargetResource @absentParams | Should Be $true - } - - It 'Fails when Ensure = Absent and group policy inheritance is not blocked on the Target' { - Mock -CommandName Get-ADDomain -MockWith {$fakeADDomain} - Mock -CommandName Import-Module -MockWith {} - Mock -CommandName Get-GPInheritance -MockWith {$fakeGPInheritanceNotBlocked} - Test-TargetResource @absentParams | Should Be $false - } - } - #endregion - - - #region Function Set-TargetResource - Describe "$($Global:DSCResourceName)\Set-TargetResource" { - It "Calls Import-GPO once" { - Mock -CommandName Get-ADDomain -MockWith {$fakeADDomain} - Mock -CommandName Import-Module -MockWith {} - Mock -CommandName Set-GPInheritance -MockWith {} - Set-TargetResource @presentParams - Assert-MockCalled -CommandName Set-GPInheritance -Times 1 -Exactly -Scope It - } - } - #endregion - - - #region Function Test-TargetDN - Describe "$($Global:DSCResourceName)\Test-TargetDN" { - It "Returns $ou,$rootDSE when given partial OU DN" { - Mock -CommandName Get-ADDomain -MockWith {$fakeADDomain} - Test-TargetDN @presentPartialOUParams | Should Be "$ou,$rootDSE" - } - - It "Returns $ou,$rootDSE when given full OU DN" { - Mock -CommandName Get-ADDomain -MockWith {$fakeADDomain} - Test-TargetDN @presentParams | Should Be "$ou,$rootDSE" - } - } - #endregion - } - #endregion -} -finally -{ - #region FOOTER - Restore-TestEnvironment -TestEnvironment $TestEnvironment - #endregion -} diff --git a/Tests/Unit/MSFT_xGPOImport.Tests.ps1 b/Tests/Unit/MSFT_xGPOImport.Tests.ps1 deleted file mode 100644 index 6a20a81..0000000 --- a/Tests/Unit/MSFT_xGPOImport.Tests.ps1 +++ /dev/null @@ -1,142 +0,0 @@ -$Global:DSCModuleName = 'xGroupPolicy' -$Global:DSCResourceName = 'MSFT_xGPOImport' - -#region HEADER -[String] $moduleRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $Script:MyInvocation.MyCommand.Path)) -if ( (-not (Test-Path -Path (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests'))) -or ` - (-not (Test-Path -Path (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1'))) ) -{ - & git @('clone','https://github.com/PowerShell/DscResource.Tests.git',(Join-Path -Path $moduleRoot -ChildPath '\DSCResource.Tests\')) -} -else -{ - & git @('-C',(Join-Path -Path $moduleRoot -ChildPath '\DSCResource.Tests\'),'pull') -} -Import-Module (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1') -Force -$TestEnvironment = Initialize-TestEnvironment ` - -DSCModuleName $Global:DSCModuleName ` - -DSCResourceName $Global:DSCResourceName ` - -TestType Unit -#endregion - -# Begin Testing -try -{ - - #region Pester Tests - - # The InModuleScope command allows you to perform white-box unit testing on the internal - # (non-exported) code of a Script Module. - InModuleScope $Global:DSCResourceName { - - #region Pester Test Initialization - function Get-GPO {} - function Import-GPO {} - $gpoName = 'Test GPO' - $domainName = 'testdomain.local' - $testParams = @{ - TargetName = $gpoName - Path = "C:\Test Path\GPO Backups\$gpoName" - BackupIdentity = $gpoName - BackupIdentityType = 'Name' - Domain = $domainName - MigrationTable = 'C:\Test Path\GPO Backups\MigTable.mitable' - Server = 'TestServer' - } - $fakeGPO = @{ - DisplayName = $gpoName - DomainName = $domainName - } - #endregion - - - #region Function Get-TargetResource - Describe "$($Global:DSCResourceName)\Get-TargetResource" { - It 'Returns a "System.Collections.Hashtable" object type' { - Mock -CommandName Import-Module -MockWith {} - Mock -CommandName Get-GPO -MockWith {return $fakeGPO} - $targetResource = Get-TargetResource @testParams - $targetResource -is [System.Collections.Hashtable] | Should Be $true - } - - It "Returns Ensure = Present when GPO is found" { - Mock -CommandName Import-Module -MockWith {} - Mock -CommandName Get-GPO -MockWith {return $fakeGPO} - $targetResource = Get-TargetResource @testParams - $targetResource.Ensure | Should Be 'Present' - } - - It "Returns TargetName = $($testParams.TargetName) when GPO is found" { - Mock -CommandName Import-Module -MockWith {} - Mock -CommandName Get-GPO -MockWith {return $fakeGPO} - $targetResource = Get-TargetResource @testParams - $targetResource.TargetName | Should Be $testParams.TargetName - } - - It "Returns Domain = $($testParams.Domain) when GPO is found" { - Mock -CommandName Import-Module -MockWith {} - Mock -CommandName Get-GPO -MockWith {return $fakeGPO} - $targetResource = Get-TargetResource @testParams - $targetResource.Domain | Should Be $testParams.Domain - } - - It "Returns Ensure = Absent when GPO is not found" { - Mock -CommandName Import-Module -MockWith {} - Mock -CommandName Get-GPO -MockWith {} - $targetResource = Get-TargetResource @testParams - $targetResource.Ensure | Should Be 'Absent' - } - - It "Returns an empty Domain when GPO is not found" { - Mock -CommandName Import-Module -MockWith {} - Mock -CommandName Get-GPO -MockWith {} - $targetResource = Get-TargetResource @testParams - $targetResource.Domain | Should Be $null - } - } - #endregion - - - #region Function Test-TargetResource - Describe "$($Global:DSCResourceName)\Test-TargetResource" { - It 'Returns a "System.Boolean" object type' { - Mock -CommandName Import-Module -MockWith {} - Mock -CommandName Get-GPO -MockWith {return $fakeGPO} - $targetResource = Test-TargetResource @testParams - $targetResource -is [System.Boolean] | Should Be $true - } - - It 'Passes when GPO found' { - Mock -CommandName Import-Module -MockWith {} - Mock -CommandName Get-GPO -MockWith {return $fakeGPO} - Test-TargetResource @testParams | Should Be $true - } - - It 'Fails when GPO not found' { - Mock -CommandName Import-Module -MockWith {} - Mock -CommandName Get-GPO -MockWith {} - Test-TargetResource @testParams | Should Be $false - } - } - #endregion - - - #region Function Set-TargetResource - Describe "$($Global:DSCResourceName)\Set-TargetResource" { - It "Calls Import-GPO once" { - Mock -CommandName Import-Module -MockWith {} - Mock -CommandName Import-GPO -MockWith {} - Set-TargetResource @testParams - Assert-MockCalled -CommandName Import-GPO -Times 1 -Exactly -Scope It - } - } - #endregion - } - #endregion -} -finally -{ - #region FOOTER - Restore-TestEnvironment -TestEnvironment $TestEnvironment - #endregion -} diff --git a/Tests/Unit/MSFT_xGPOLink.Tests.ps1 b/Tests/Unit/MSFT_xGPOLink.Tests.ps1 deleted file mode 100644 index a25d220..0000000 --- a/Tests/Unit/MSFT_xGPOLink.Tests.ps1 +++ /dev/null @@ -1,199 +0,0 @@ -$Global:DSCModuleName = 'xGroupPolicy' -$Global:DSCResourceName = 'MSFT_xGPOLink' - -#region HEADER -[String] $moduleRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $Script:MyInvocation.MyCommand.Path)) -if ( (-not (Test-Path -Path (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests'))) -or ` - (-not (Test-Path -Path (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1'))) ) -{ - & git @('clone','https://github.com/PowerShell/DscResource.Tests.git',(Join-Path -Path $moduleRoot -ChildPath '\DSCResource.Tests\')) -} -else -{ - & git @('-C',(Join-Path -Path $moduleRoot -ChildPath '\DSCResource.Tests\'),'pull') -} -Import-Module (Join-Path -Path $moduleRoot -ChildPath 'DSCResource.Tests\TestHelper.psm1') -Force -$TestEnvironment = Initialize-TestEnvironment ` - -DSCModuleName $Global:DSCModuleName ` - -DSCResourceName $Global:DSCResourceName ` - -TestType Unit -#endregion - -# Begin Testing -try -{ - - #region Pester Tests - - # The InModuleScope command allows you to perform white-box unit testing on the internal - # (non-exported) code of a Script Module. - InModuleScope $Global:DSCResourceName { - - #region Pester Test Initialization - function Get-ADDomain {} - function Get-GPO {} - function Get-GPInheritance {} - function New-GPLink {} - function Set-GPLink {} - function Remove-GPLink {} - $gpoName = 'Test GPO' - $gpoId = '8451f164-0cff-4d3f-b4d1-6a54640c80ae' - $rootDSE = 'DC=testdomain,DC=local' - $ou = 'OU=Test OU' - $domainName = 'testdomain.local' - $presentParams = @{ - Identity = $gpoName - IdentityType = 'Name' - Target = "$ou,$rootDSE" - Domain = $domainName - Enforced = 'No' - LinkEnabled = 'Yes' - Order = 1 - Ensure = 'Present' - } - $absentParams = $presentParams.Clone() - $absentParams.Ensure = 'Absent' - $gpInheritanceCorrectProperties = @{ - GpoLinks = @{ - GpoId = $gpoId - DisplayName = $gpoName - Enabled = $true - Enforced = $false - Target = "$ou,$rootDSE" - Order = 1 - } - } - $gpInheritanceIncorrectProperties = @{ - GpoLinks = @{ - GpoId = $gpoId - DisplayName = $gpoName - Enabled = $false - Enforced = $true - Target = "$ou,$rootDSE" - Order = 2 - } - } - $gpo = @{ - DisplayName = $gpoName - Id = $gpoId - DomainName = $domainName - } - #endregion - - - #region Function Get-TargetResource - Describe "$($Global:DSCResourceName)\Get-TargetResource" { - It 'Returns a "System.Collections.Hashtable" object type' { - Mock -CommandName Import-Module -MockWith {} - Mock -CommandName Get-GPInheritance -MockWith {} - Mock -CommandName Get-GPO -MockWith {return $gpo} - $targetResource = Get-TargetResource @presentParams - $targetResource -is [System.Collections.Hashtable] | Should Be $true - } - - It "Returns Ensure = Present when GPO Link is found" { - Mock -CommandName Import-Module -MockWith {} - Mock -CommandName Get-GPInheritance -MockWith {return $gpInheritanceCorrectProperties} - Mock -CommandName Get-GPO -MockWith {return $gpo} - $targetResource = Get-TargetResource @presentParams - $targetResource.Ensure | Should Be 'Present' - } - - It "Returns Ensure = Absent when GPO Link is not found" { - Mock -CommandName Import-Module -MockWith {} - Mock -CommandName Get-GPInheritance -MockWith {} - Mock -CommandName Get-GPO -MockWith {return $gpo} - $targetResource = Get-TargetResource @presentParams - $targetResource.Ensure | Should Be 'Absent' - } - } - #endregion - - - #region Function Test-TargetResource - Describe "$($Global:DSCResourceName)\Test-TargetResource" { - It 'Returns a "System.Boolean" object type' { - Mock -CommandName Import-Module -MockWith {} - Mock -CommandName Get-GPInheritance -MockWith {} - Mock -CommandName Get-GPO -MockWith {return $gpo} - $targetResource = Test-TargetResource @presentParams - $targetResource -is [System.Boolean] | Should Be $true - } - - It 'Passes when Ensure = Present and GPO Link found with correct properties' { - Mock -CommandName Import-Module -MockWith {} - Mock -CommandName Get-GPInheritance -MockWith {return $gpInheritanceCorrectProperties} - Mock -CommandName Get-GPO -MockWith {return $gpo} - Test-TargetResource @presentParams | Should Be $true - } - - It 'Fails when Ensure = Present and GPO Link found with incorrect properties' { - Mock -CommandName Import-Module -MockWith {} - Mock -CommandName Get-GPInheritance -MockWith {return $gpInheritanceIncorrectProperties} - Mock -CommandName Get-GPO -MockWith {return $gpo} - Test-TargetResource @presentParams | Should Be $false - } - - It 'Fails when Ensure = Present and GPO Link not found' { - Mock -CommandName Import-Module -MockWith {} - Mock -CommandName Get-GPInheritance -MockWith {} - Mock -CommandName Get-GPO -MockWith {return $gpo} - Test-TargetResource @presentParams | Should Be $false - } - - It 'Passes when Ensure = Absent and GPO Link not found' { - Mock -CommandName Import-Module -MockWith {} - Mock -CommandName Get-GPInheritance -MockWith {} - Mock -CommandName Get-GPO -MockWith {return $gpo} - Test-TargetResource @absentParams | Should Be $true - } - - It 'Failes when Ensure = Absent and GPO Link found' { - Mock -CommandName Import-Module -MockWith {} - Mock -CommandName Get-GPInheritance -MockWith {return $gpInheritanceCorrectProperties} - Mock -CommandName Get-GPO -MockWith {return $gpo} - Test-TargetResource @absentParams | Should Be $false - } - } - #endregion - - - #region Function Set-TargetResource - Describe "$($Global:DSCResourceName)\Set-TargetResource" { - It "Calls New-GPLink once when GPO Link not found" { - Mock -CommandName Import-Module -MockWith {} - Mock -CommandName Get-GPInheritance -MockWith {} - Mock -CommandName Get-GPO -MockWith {return $gpo} - Mock -CommandName New-GPLink -MockWith {} - Set-TargetResource @presentParams - Assert-MockCalled -CommandName New-GPLink -Times 1 -Exactly -Scope It - } - - It "Calls Set-GPLink once when GPO Link is found but the properties aren't correct" { - Mock -CommandName Import-Module -MockWith {} - Mock -CommandName Get-GPInheritance -MockWith {return $gpInheritanceIncorrectProperties} - Mock -CommandName Get-GPO -MockWith {return $gpo} - Mock -CommandName Set-GPLink -MockWith {} - Set-TargetResource @presentParams - Assert-MockCalled -CommandName Set-GPLink -Times 1 -Exactly -Scope It - } - - It "Calls Remove-GPLink once when Ensure = Absent and GPO Link found" { - Mock -CommandName Import-Module -MockWith {} - Mock -CommandName Get-GPInheritance -MockWith {return $gpInheritanceCorrectProperties} - Mock -CommandName Get-GPO -MockWith {return $gpo} - Mock -CommandName Remove-GPLink -MockWith {} - Set-TargetResource @absentParams - Assert-MockCalled -CommandName Remove-GPLink -Times 1 -Exactly -Scope It - } - } - #endregion - } - #endregion -} -finally -{ - #region FOOTER - Restore-TestEnvironment -TestEnvironment $TestEnvironment - #endregion -} diff --git a/appveyor.yml b/appveyor.yml index 7078d78..2b2d9e6 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -43,7 +43,7 @@ deploy_script: - ps: | # Creating project artifact $stagingDirectory = (Resolve-Path ..).Path - $manifest = Join-Path $pwd "xGroupPolicy.psd1" + $manifest = Join-Path $pwd "GroupPolicyDsc.psd1" (Get-Content $manifest -Raw).Replace("1.0.0.0", $env:APPVEYOR_BUILD_VERSION) | Out-File $manifest $zipFilePath = Join-Path $stagingDirectory "$(Split-Path $pwd -Leaf).zip" Add-Type -assemblyname System.IO.Compression.FileSystem diff --git a/xGroupPolicy.psd1 b/xGroupPolicy.psd1 deleted file mode 100644 index 8f22b9ee1d57ca1d9185b995959ca619ce04d6e4..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6672 zcmc(jYi|=r6o%(>rT&MN@_|q_p`k!YrAk;h36UU05TIWjJ9gdrR>x^T6@R_$`^@oS zcD%c(b5j*LyE`-I%zN%<=AXYe!q?%eun~&zDojH!oQF|3)z>(5!XyksUtecop^?7k z=W(XI?q2v94m3U$5F5or)W@55t476L$6gVfapOPfE1VKMQ}w5$E+*=;p#Wi&Bl_ZZ5S+c%s>fP|k%8 zO_b&BYtA&(kzUR;*VRap=t5tM@T=(fKh%n$8LBk*|zlky~cO+_Eh{& z;@Gan9>%X9G}_UAk7fPc733|U1A|%gGW~!lUv0RmKAG!=`LVo+I6()t)1Offy*2mE zc^rw?SoB3O1V?&bgn>r!$08i-yDOO{;y%)Epna>DW*Wu62U$Q5o_sEspdIH^gu1^c3!)PXeCk4LjPFIHcq$62} zwdA?Eoz_E6lv<6sJ=8CjJQFgrW{&$V>~NRTtYeGyWMUOjhUT#uSz$XIg*|1NBJ69% za?yom=i&EjdsJKW3-KkBRk_}tJY+Kbp12(A&#L4|QV4s=s=8RT@b7ukIweBda;rnH6>r{PNsB$lmzo zMATlh$m`@sv}W{W-f$)VHdnL_&At)0a#k$ocH}_TXVU!rtYd6Ndz}i)i4YFO<8qmi zrV~3N^6p*Wu18dlKJRzEe?@{#Mf^;%>_ksWHpC~bh7c>*kpFJ2ZnP6U@LaVUK3M3s zEtY!ZGX67Vr>W{HzTt7yWVK^;1G6Ycz04nF&(TtHx?1zs+;$f+tC$XwAFt_r6qKe)>nu7Z6vmZ~vIw!>e@Y2*kyQ;@6u+{tX-L6m3dWw9tHE_7q`=ACau zw|bI#ke#clp5xsZ)yeU!N>LwE`>~3o{uA6L@2Sqip6{?Ao=S(;oR_M+K)RRlu^jx( zO0WD}oO|+NYU@o9JoX@(ux5HcY z4}PlQ4uoocGb9`0*On~ZSgq*J64!cM)r$2}I1lHUM;_O*Pjtr5dc-*qMqe9@gyx04O&LVA+A zd``~2fG_d~E1hS$@8N!~{=8}RIoD}IWfn;HZiTq;mt${Q<*PSDaV%7WXqAq=#uRp8QPP-~MJ8{3)4;|Ifk+f|m zGDe2#v67ei%>n+>ixw&OG1hDTS3gJI`FWW^& Date: Wed, 3 Aug 2016 09:59:38 -0500 Subject: [PATCH 08/13] Removed x from in front of resources. --- .../MSFT_GPInheritance.psm1 | 137 +++++++++ .../MSFT_GPInheritance.schema.mof | 8 + .../MSFT_GPOImport/MSFT_GPOImport.psm1 | 104 +++++++ .../MSFT_GPOImport/MSFT_GPOImport.schema.mof | 12 + DSCResources/MSFT_GPOLink/MSFT_GPOLink.psm1 | 277 ++++++++++++++++++ .../MSFT_GPOLink/MSFT_GPOLink.schema.mof | 13 + Examples/BlockInheritance.ps1 | 16 + Examples/GpoImportByGuid.ps1 | 19 ++ .../GpoImportByNameWithMigrationTable.ps1 | 21 ++ Examples/GpoLinkByGuidAndDisable.ps1 | 20 ++ .../GpoLinkByNameAndEnforceWithLinkOrder.ps1 | 21 ++ Examples/UnblockInheritance.ps1 | 17 ++ GroupPolicyDsc.psd1 | Bin 0 -> 6676 bytes .../MSFT_GPInheritance.Integration.tests.ps1 | 64 ++++ .../Integration/MSFT_GPInheritance.config.ps1 | 16 + .../MSFT_GPOImport.Integration.tests.ps1 | 68 +++++ Tests/Integration/MSFT_GPOImport.config.ps1 | 25 ++ .../MSFT_GPOLink.Integration.tests.ps1 | 68 +++++ Tests/Integration/MSFT_GPOLink.config.ps1 | 23 ++ Tests/Unit/MSFT_GPInheritance.Tests.ps1 | 163 +++++++++++ Tests/Unit/MSFT_GPOImport.Tests.ps1 | 142 +++++++++ Tests/Unit/MSFT_GPOLink.Tests.ps1 | 199 +++++++++++++ 22 files changed, 1433 insertions(+) create mode 100644 DSCResources/MSFT_GPInheritance/MSFT_GPInheritance.psm1 create mode 100644 DSCResources/MSFT_GPInheritance/MSFT_GPInheritance.schema.mof create mode 100644 DSCResources/MSFT_GPOImport/MSFT_GPOImport.psm1 create mode 100644 DSCResources/MSFT_GPOImport/MSFT_GPOImport.schema.mof create mode 100644 DSCResources/MSFT_GPOLink/MSFT_GPOLink.psm1 create mode 100644 DSCResources/MSFT_GPOLink/MSFT_GPOLink.schema.mof create mode 100644 Examples/BlockInheritance.ps1 create mode 100644 Examples/GpoImportByGuid.ps1 create mode 100644 Examples/GpoImportByNameWithMigrationTable.ps1 create mode 100644 Examples/GpoLinkByGuidAndDisable.ps1 create mode 100644 Examples/GpoLinkByNameAndEnforceWithLinkOrder.ps1 create mode 100644 Examples/UnblockInheritance.ps1 create mode 100644 GroupPolicyDsc.psd1 create mode 100644 Tests/Integration/MSFT_GPInheritance.Integration.tests.ps1 create mode 100644 Tests/Integration/MSFT_GPInheritance.config.ps1 create mode 100644 Tests/Integration/MSFT_GPOImport.Integration.tests.ps1 create mode 100644 Tests/Integration/MSFT_GPOImport.config.ps1 create mode 100644 Tests/Integration/MSFT_GPOLink.Integration.tests.ps1 create mode 100644 Tests/Integration/MSFT_GPOLink.config.ps1 create mode 100644 Tests/Unit/MSFT_GPInheritance.Tests.ps1 create mode 100644 Tests/Unit/MSFT_GPOImport.Tests.ps1 create mode 100644 Tests/Unit/MSFT_GPOLink.Tests.ps1 diff --git a/DSCResources/MSFT_GPInheritance/MSFT_GPInheritance.psm1 b/DSCResources/MSFT_GPInheritance/MSFT_GPInheritance.psm1 new file mode 100644 index 0000000..8bafaef --- /dev/null +++ b/DSCResources/MSFT_GPInheritance/MSFT_GPInheritance.psm1 @@ -0,0 +1,137 @@ +function Get-TargetResource +{ + [OutputType([Hashtable])] + param + ( + [parameter(Mandatory = $true)] + [string]$Target, + [string]$Domain, + [string]$Server, + [ValidateSet('Present','Absent')] + [string]$Ensure = 'Present' + ) + $Target = Test-TargetDN @PSBoundParameters + $targetResource = @{ + Target = $Target + Domain = $null + Server = $null + Ensure = $null + } + $params = @{Target = $Target} + if ($Domain) + { + $targetResource.Domain = $Domain + $params += @{Domain = $Domain} + } + if ($Server) + { + $targetResource.Server = $Server + $params += @{Server = $Server} + } + Import-Module GroupPolicy -Verbose:$false + Write-Verbose 'Getting Group Policy Inheritance' + $gpoInheritanceBlocked = (Get-GPInheritance @params).GpoInheritanceBlocked + if (!$gpoInheritanceBlocked) {$targetResource.Ensure = 'Present'} + else {$targetResource.Ensure = 'Absent'} + Write-Output $targetResource +} + +function Set-TargetResource +{ + param + ( + [parameter(Mandatory = $true)] + [string]$Target, + [string]$Domain, + [string]$Server, + [ValidateSet('Present','Absent')] + [string]$Ensure = 'Present' + ) + if ($Ensure -eq 'Present') + { + Write-Verbose 'Enabling Group Policy Inheritance' + $isBlocked = 'No' + } + else + { + Write-Verbose 'Disabling Group Policy Inheritance' + $isBlocked = 'Yes' + } + $Target = Test-TargetDN @PSBoundParameters + $params = @{ + Target = $Target + IsBlocked = $IsBlocked + } + if ($Domain) + { + $params += @{Domain = $Domain} + } + if ($Server) + { + $params += @{Server = $Server} + } + Import-Module GroupPolicy -Verbose:$false + $null = Set-GPInheritance @params +} + +function Test-TargetResource +{ +[OutputType([Boolean])] + param + ( + [parameter(Mandatory = $true)] + [string]$Target, + [string]$Domain, + [string]$Server, + [ValidateSet('Present','Absent')] + [string]$Ensure = 'Present' + ) + $targetResource = Get-TargetResource @PSBoundParameters + switch ($Ensure) + { + Present + { + if ($targetResource.Ensure -eq 'Present') {$true} + else {$false} + } + Absent + { + if ($targetResource.Ensure -eq 'Absent') {$true} + else {$false} + } + } +} + +function Test-TargetDN +{ + param + ( + [parameter(Mandatory = $true)] + [string]$Target, + [string]$Domain, + [string]$Server, + [ValidateSet('Present','Absent')] + [string]$Ensure = 'Present' + ) + $params = @{} + if ($Server) {$params += @{Server = $Server}} + Write-Verbose "Checking the Domain Distinguished Name is present on the Target Distinguished Name." + $domainDN = (Get-ADDomain @params).DistinguishedName + if ($Target -like "*$domainDN") + { + Write-Verbose "Target has full DN." + } + else + { + Write-Verbose "Adding the Domain Distinguished Name to the Target DN." + if ($Target.EndsWith(",")) + { + $Target = "$Target$domainDN" + } + else + { + $Target = "$Target,$domainDN" + } + } + $Target +} diff --git a/DSCResources/MSFT_GPInheritance/MSFT_GPInheritance.schema.mof b/DSCResources/MSFT_GPInheritance/MSFT_GPInheritance.schema.mof new file mode 100644 index 0000000..be3217b --- /dev/null +++ b/DSCResources/MSFT_GPInheritance/MSFT_GPInheritance.schema.mof @@ -0,0 +1,8 @@ +[ClassVersion("1.0.0"), FriendlyName("GPInheritance")] +class MSFT_GPInheritance : OMI_BaseResource +{ + [Key] String Target; + [write] String Domain; + [write] String Server; + [write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] string Ensure; +}; diff --git a/DSCResources/MSFT_GPOImport/MSFT_GPOImport.psm1 b/DSCResources/MSFT_GPOImport/MSFT_GPOImport.psm1 new file mode 100644 index 0000000..c7c50e4 --- /dev/null +++ b/DSCResources/MSFT_GPOImport/MSFT_GPOImport.psm1 @@ -0,0 +1,104 @@ +function Get-TargetResource +{ + [OutputType([Hashtable])] + param + ( + [parameter(Mandatory = $true)] + [string]$TargetName, + [parameter(Mandatory = $true)] + [string]$Path, + [parameter(Mandatory = $true)] + [string]$BackupIdentity, + [ValidateSet('Name','Guid')] + [string]$BackupIdentityType = 'Name', + [string]$Domain, + [string]$MigrationTable, + [string]$Server, + [ValidateSet('Present')] + [string]$Ensure = 'Present' + ) + Import-Module GroupPolicy -Verbose:$false + $params = @{ + Name = $TargetName + ErrorAction = 'SilentlyContinue' + } + if ($Domain) {$params += @{Domain = $Domain}} + if ($Server) {$params += @{Server = $Server}} + Write-Verbose 'Getting GPO' + $gpo = Get-GPO @params + $targetResource = @{ + TargetName = $TargetName + Path = $Path + BackupIdentity = $BackupIdentity + BackupIdentityType = $BackupIdentityType + Domain = $null + MigrationTable = $null + Server = $null + Ensure = 'Absent' + } + if ($MigrationTable) {$targetResource.MigrationTable = $MigrationTable} + if ($Server) {$targetResource.Server = $Server} + if ($gpo) + { + $targetResource.Domain = $gpo.DomainName + $targetResource.Ensure = 'Present' + } + $targetResource +} + +function Set-TargetResource +{ + param + ( + [parameter(Mandatory = $true)] + [string]$TargetName, + [parameter(Mandatory = $true)] + [string]$Path, + [parameter(Mandatory = $true)] + [string]$BackupIdentity, + [ValidateSet('Name','Guid')] + [string]$BackupIdentityType = 'Name', + [string]$Domain, + [string]$MigrationTable, + [string]$Server, + [ValidateSet('Present')] + [string]$Ensure = 'Present' + ) + Import-Module GroupPolicy -Verbose:$false + $params = @{ + TargetName = $TargetName + Path = $Path + CreateIfNeeded = $true + } + if ($BackupIdentityType -eq 'Name') {$params += @{BackupGpoName = $BackupIdentity}} + else {$params += @{BackupId = $BackupIdentity}} + if ($Domain) {$params += @{Domain = $Domain}} + if ($MigrationTable) {$params += @{MigrationTable = $MigrationTable}} + if ($Server) {$params += @{Server = $Server}} + Write-Verbose 'Importing GPO' + $null = Import-GPO @params +} + +function Test-TargetResource +{ +[OutputType([Boolean])] + param + ( + [parameter(Mandatory = $true)] + [string]$TargetName, + [parameter(Mandatory = $true)] + [string]$Path, + [parameter(Mandatory = $true)] + [string]$BackupIdentity, + [ValidateSet('Name','Guid')] + [string]$BackupIdentityType = 'Name', + [string]$Domain, + [string]$MigrationTable, + [string]$Server, + [ValidateSet('Present')] + [string]$Ensure = 'Present' + ) + $targetResource = Get-TargetResource @PSBoundParameters + if ($targetResource.Ensure -eq 'Present') {$true} + else {$false} +} diff --git a/DSCResources/MSFT_GPOImport/MSFT_GPOImport.schema.mof b/DSCResources/MSFT_GPOImport/MSFT_GPOImport.schema.mof new file mode 100644 index 0000000..9c49d47 --- /dev/null +++ b/DSCResources/MSFT_GPOImport/MSFT_GPOImport.schema.mof @@ -0,0 +1,12 @@ +[ClassVersion("1.0.0"), FriendlyName("GPOImport")] +class MSFT_GPOImport : OMI_BaseResource +{ + [Key] String TargetName; + [required] String Path; + [required] String BackupIdentity; + [write,ValueMap{"Name", "Guid"},Values{"Name", "Guid"}] string BackupIdentityType; + [write] String Domain; + [write] String MigrationTable; + [write] String Server; + [write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] string Ensure; +}; diff --git a/DSCResources/MSFT_GPOLink/MSFT_GPOLink.psm1 b/DSCResources/MSFT_GPOLink/MSFT_GPOLink.psm1 new file mode 100644 index 0000000..f5a77a4 --- /dev/null +++ b/DSCResources/MSFT_GPOLink/MSFT_GPOLink.psm1 @@ -0,0 +1,277 @@ +function Get-TargetResource { + [OutputType([Hashtable])] + param + ( + [parameter(Mandatory = $true)] + [string]$Identity, + [ValidateSet('Name','Guid')] + [string]$IdentityType = 'Name', + [parameter(Mandatory = $true)] + [string]$Target, + [string]$Domain, + [ValidateSet('Yes','No')] + [string]$Enforced, + [ValidateSet('Yes','No')] + [string]$LinkEnabled, + [int16]$Order, + [string]$Server, + [ValidateSet('Present','Absent')] + [string]$Ensure = 'Present' + ) + $target = Test-TargetDN @PSBoundParameters + $gpInheritanceparams = @{ + Target = $target + } + if ($Server) {$gpInheritanceparams += @{Server = $Server}} + if ($Domain) {$gpInheritanceparams += @{Domain = $Domain}} + Import-Module GroupPolicy -Verbose:$false + Write-Verbose 'Getting GPO Links' + $gpoLinks = (Get-GPInheritance @gpInheritanceparams).GpoLinks + $gpo = Get-GpoInfo @PSBoundParameters + $targetResource = @{ + Identity = $Identity + IdentityType = $IdentityType + Target = $Target + Domain = $null + Enforced = $null + LinkEnabled = $null + Order = $null + Server = $Server + Ensure = 'Absent' + } + if ($gpo) + { + # Using the GpoId attribute of the GPO Links instead of the + # Name attribute because the Name attribute may take a while + # to replicate to all DCs if the GPO was recently created. + $targetLink = $gpoLinks | where {$_.GpoId -eq $gpo.Id} + if ($targetLink) + { + if ($targetLink.Enabled) {$targetResource.LinkEnabled = 'Yes'} + else {$targetResource.LinkEnabled = 'No'} + if ($targetLink.Enforced) {$targetResource.Enforced = 'Yes'} + else {$targetResource.Enforced = 'No'} + $targetResource.Order = $targetLink.Order + $targetResource.Ensure = 'Present' + } + $targetResource.Domain = $gpo.DomainName + } + $targetResource +} + +function Set-TargetResource { + param + ( + [parameter(Mandatory = $true)] + [string]$Identity, + [ValidateSet('Name','Guid')] + [string]$IdentityType = 'Name', + [parameter(Mandatory = $true)] + [string]$Target, + [string]$Domain, + [ValidateSet('Yes','No')] + [string]$Enforced, + [ValidateSet('Yes','No')] + [string]$LinkEnabled, + [int16]$Order, + [string]$Server, + [ValidateSet('Present','Absent')] + [string]$Ensure = 'Present' + ) + Import-Module GroupPolicy -Verbose:$false + $targetResource = Get-TargetResource @PSBoundParameters + $gpo = Get-GpoInfo @PSBoundParameters + if ($Ensure -eq 'Present') + { + if ($targetResource.Ensure -eq 'Present') + { + $setParams = @{Target = $targetResource.Target} + if ($IdentityType -eq 'Name') + { + # Using the GpoId attribute of the GPO Links instead of the + # Name attribute because the Name attribute may take a while + # to replicate to all DCs if the GPO was recently created. + $setParams += @{Guid = $gpo.Id} + } + else {$setParams += @{Guid = $Identity}} + if ($Domain) {$setParams += @{Domain = $Domain}} + if ($Enforced -and $targetResource.Enforced -ne $Enforced) + { + $setParams += @{Enforced = $Enforced} + } + if ($LinkEnabled -and $targetResource.LinkEnabled -ne $LinkEnabled) + { + $setParams += @{LinkEnabled = $LinkEnabled} + } + if ($Order -and $targetResource.Order -ne $Order) + { + $setParams += @{Order = $Order} + } + if ($Server) {$setParams += @{Server = $Server}} + Write-Verbose 'Updating GPO Link' + Set-GPLink @setParams + } + else + { + $newParams = @{Target = $targetResource.Target} + if ($IdentityType -eq 'Name') + { + # Using the GpoId attribute of the GPO Links instead of the + # Name attribute because the Name attribute may take a while + # to replicate to all DCs if the GPO was recently created. + $newParams += @{Guid = $gpo.Id} + } + else {$newParams += @{Guid = $Identity}} + if ($Domain) {$newParams += @{Domain = $Domain}} + if ($Enforced) {$newParams += @{Enforced = $Enforced}} + if ($LinkEnabled) {$newParams += @{LinkEnabled = $LinkEnabled}} + if ($Order) {$newParams += @{Order = $Order}} + if ($Server) {$newParams += @{Server = $Server}} + Write-Verbose 'Creating GPO Link' + New-GPLink @newParams + } + } + else + { + $removeParams = @{Target = $targetResource.Target} + if ($IdentityType -eq 'Name') + { + # Using the GpoId attribute of the GPO Links instead of the + # Name attribute because the Name attribute may take a while + # to replicate to all DCs if the GPO was recently created. + $removeParams += @{Guid = $gpo.Id} + } + else {$removeParams += @{Guid = $Identity}} + if ($Domain) {$removeParams += @{Domain = $Domain}} + if ($Server) {$removeParams += @{Server = $Server}} + Write-Verbose 'Removing GPO Link' + Remove-GPLink @removeParams + } +} + +function Test-TargetResource { +[OutputType([Boolean])] + param + ( + [parameter(Mandatory = $true)] + [string]$Identity, + [ValidateSet('Name','Guid')] + [string]$IdentityType = 'Name', + [parameter(Mandatory = $true)] + [string]$Target, + [string]$Domain, + [ValidateSet('Yes','No')] + [string]$Enforced, + [ValidateSet('Yes','No')] + [string]$LinkEnabled, + [int16]$Order, + [string]$Server, + [ValidateSet('Present','Absent')] + [string]$Ensure = 'Present' + ) + $targetResource = Get-TargetResource @PSBoundParameters + $targetResourceInCompliance = $true + if ($Ensure -eq 'Present') + { + if ($targetResource.Ensure -eq 'Present') + { + if ($Enforced -and $targetResource.Enforced -ne $Enforced) + { + $targetResourceInCompliance = $false + } + if ($LinkEnabled -and $targetResource.LinkEnabled -ne $LinkEnabled) + { + $targetResourceInCompliance = $false + } + if ($Order -and $targetResource.Order -ne $Order) + { + $targetResourceInCompliance = $false + } + } + else {$targetResourceInCompliance = $false} + } + elseif ($targetResource.Ensure -eq 'Present') + { + $targetResourceInCompliance = $false + } + $targetResourceInCompliance +} + +function Test-TargetDN +{ + param + ( + [parameter(Mandatory = $true)] + [string]$Identity, + [ValidateSet('Name','Guid')] + [string]$IdentityType = 'Name', + [parameter(Mandatory = $true)] + [string]$Target, + [string]$Domain, + [ValidateSet('Yes','No')] + [string]$Enforced, + [ValidateSet('Yes','No')] + [string]$LinkEnabled, + [int16]$Order, + [string]$Server, + [ValidateSet('Present','Absent')] + [string]$Ensure = 'Present' + ) + $params = @{} + if ($Server) {$params += @{Server = $Server}} + Write-Verbose "Checking the Domain Distinguished Name is present on the Target Distinguished Name." + $domainDN = (Get-ADDomain @params).DistinguishedName + if ($Target -like "*$domainDN") + { + Write-Verbose "Target has full DN." + } + else + { + Write-Verbose "Adding the Domain Distinguished Name to the Target DN." + if ($Target.EndsWith(",")) + { + $Target = "$Target$domainDN" + } + else + { + $Target = "$Target,$domainDN" + } + } + $Target +} + +function Get-GpoInfo +{ + param + ( + [parameter(Mandatory = $true)] + [string]$Identity, + [ValidateSet('Name','Guid')] + [string]$IdentityType = 'Name', + [parameter(Mandatory = $true)] + [string]$Target, + [string]$Domain, + [ValidateSet('Yes','No')] + [string]$Enforced, + [ValidateSet('Yes','No')] + [string]$LinkEnabled, + [int16]$Order, + [string]$Server, + [ValidateSet('Present','Absent')] + [string]$Ensure = 'Present' + ) + $gpoParams = @{} + if ($Server) + { + $gpoParams += @{Server = $Server} + } + if ($Domain) + { + $gpoParams += @{Domain = $Domain} + } + if ($IdentityType -eq 'Name') {$gpoParams += @{Name = $Identity}} + else {$gpoParams += @{Guid = $Identity}} + Import-Module GroupPolicy -Verbose:$false + Write-Verbose 'Getting GPO' + Get-GPO @gpoParams +} diff --git a/DSCResources/MSFT_GPOLink/MSFT_GPOLink.schema.mof b/DSCResources/MSFT_GPOLink/MSFT_GPOLink.schema.mof new file mode 100644 index 0000000..8cf3706 --- /dev/null +++ b/DSCResources/MSFT_GPOLink/MSFT_GPOLink.schema.mof @@ -0,0 +1,13 @@ +[ClassVersion("1.0.0"), FriendlyName("GPOLink")] +class MSFT_GPOLink : OMI_BaseResource +{ + [Key] String Identity; + [Write,ValueMap{"Name", "Guid"},Values{"Name", "Guid"}] String IdentityType; + [Key] String Target; + [Write] String Domain; + [Write,ValueMap{"Yes", "No"},Values{"Yes", "No"}] String Enforced; + [Write,ValueMap{"Yes", "No"},Values{"Yes", "No"}] String LinkEnabled; + [Write] Sint16 Order; + [Write] String Server; + [Write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] String Ensure; +}; diff --git a/Examples/BlockInheritance.ps1 b/Examples/BlockInheritance.ps1 new file mode 100644 index 0000000..a49baa8 --- /dev/null +++ b/Examples/BlockInheritance.ps1 @@ -0,0 +1,16 @@ +# In this example, we block inheritance on the Example OU. + +configuration BlockInheritance +{ + Import-DscResource -Module GPInheritance + + Node $AllNodes.NodeName + { + GPInheritance ExampleOU + { + Target = 'OU=Example,DC=testdomain,DC=local' + Ensure = 'Absent' + } + } +} +BlockInheritance diff --git a/Examples/GpoImportByGuid.ps1 b/Examples/GpoImportByGuid.ps1 new file mode 100644 index 0000000..887e012 --- /dev/null +++ b/Examples/GpoImportByGuid.ps1 @@ -0,0 +1,19 @@ +# In this example, we import group policy settings into the Example GPO by specifying the backup GUID. + +configuration ImportByGuid +{ + Import-DscResource -Module GPOImport + + Node $AllNodes.NodeName + { + GPOImport ExampleOU + { + TargetName = 'Example' + Path = "C:\GPO Backups\Example" + BackupIdentity = '7b230cb8-67fc-433d-812f-c93b53310dcf' + BackupIdentityType = 'Guid' + Ensure = 'Present' + } + } +} +ImportByGuid diff --git a/Examples/GpoImportByNameWithMigrationTable.ps1 b/Examples/GpoImportByNameWithMigrationTable.ps1 new file mode 100644 index 0000000..cc9f771 --- /dev/null +++ b/Examples/GpoImportByNameWithMigrationTable.ps1 @@ -0,0 +1,21 @@ +# In this example, we import group policy settings into the Example GPO by specifying the backup name. +# We also use a migration table. + +configuration ImportByName +{ + Import-DscResource -Module GPOImport + + Node $AllNodes.NodeName + { + GPOImport ExampleOU + { + TargetName = 'Example' + Path = "C:\GPO Backups\Example" + BackupIdentity = 'Example' + BackupIdentityType = 'Name' + MigrationTable = 'C:\GPO Backups\ExampleMigTable.mitable' + Ensure = 'Present' + } + } +} +ImportByName diff --git a/Examples/GpoLinkByGuidAndDisable.ps1 b/Examples/GpoLinkByGuidAndDisable.ps1 new file mode 100644 index 0000000..9ac6d1f --- /dev/null +++ b/Examples/GpoLinkByGuidAndDisable.ps1 @@ -0,0 +1,20 @@ +# In this example, we link a GPO by GUID to the Example OU and disable the link. +# We also leave off the domain part of the OU DN so it's generated automatically for us. + +configuration LinkGPOByGuidAndDisable +{ + Import-DscResource -Module GPOLink + + Node $AllNodes.NodeName + { + GPOLink ExampleOU + { + Identity = '9b74f3ec-a20e-4567-a1cd-f0b13a339037' + IdentityType = 'Guid' + Target = 'OU=Example,' + LinkEnabled = 'No' + Ensure = 'Present' + } + } +} +LinkGPOByGuidAndDisable diff --git a/Examples/GpoLinkByNameAndEnforceWithLinkOrder.ps1 b/Examples/GpoLinkByNameAndEnforceWithLinkOrder.ps1 new file mode 100644 index 0000000..980c63d --- /dev/null +++ b/Examples/GpoLinkByNameAndEnforceWithLinkOrder.ps1 @@ -0,0 +1,21 @@ +# In this example, we link the Example GPO by name to the Example OU and enforce the link. +# We also change the link order to 1. + +configuration LinkEnforcedGPOByName +{ + Import-DscResource -Module GPOLink + + Node $AllNodes.NodeName + { + GPOLink ExampleOU + { + Identity = 'Example' + IdentityType = 'Name' + Target = 'OU=Example,DC=testdomain,DC=local' + Enforced = 'Yes' + Order = 1 + Ensure = 'Present' + } + } +} +LinkEnforcedGPOByName diff --git a/Examples/UnblockInheritance.ps1 b/Examples/UnblockInheritance.ps1 new file mode 100644 index 0000000..90bac4e --- /dev/null +++ b/Examples/UnblockInheritance.ps1 @@ -0,0 +1,17 @@ +# In this example, we unblock inheritance on the Example OU. +# We also leave off the domain part of the OU DN so it's generated automatically for us. + +configuration UnblockInheritance +{ + Import-DscResource -Module GPInheritance + + Node $AllNodes.NodeName + { + GPInheritance ExampleOU + { + Target = 'OU=Example,' + Ensure = 'Present' + } + } +} +UnblockInheritance diff --git a/GroupPolicyDsc.psd1 b/GroupPolicyDsc.psd1 new file mode 100644 index 0000000000000000000000000000000000000000..0056ccb135743af16c6998cf3c7061831720f25b GIT binary patch literal 6676 zcmc(jYi|=r6o%(>rT&MN@_|q_p`k#bQY9>MArjCi1n5^^V%M#2b({uN@z>kF&m13S z$Ge+4H&v0dyEAjnyyt#q{`q?&d>y_D8=(lV!!-25c^HLLeT_pqOu{hq^>r2&8tH3( z9%sty?u7%5PDM8hM|zG#(+!`(uBf`<-jciTaUgCJ{pRAn(6c9g9j*RR&li#ZC%t{p z8+#blWwcXqgZ5!~5O%^d{eKv~)7z60E%eXBUvb2Fy%n~(kj|oH3=tD$&TIdRI+X9`+JS==ZSb5LQ*me+Cq9OE5gbw4|I$GFh;9Q?A za(R;H=5|^SIZZdLW@Lr!@Fwgj%M@W> zGnR`kG&>K!U)!U0MZXYVGFg@D?a4zX!|#d9vHq+|jwA(9ajxee&d>F3b;>gBrh1Q8 zs>5Wo>v^BiuOrD()OS}ntaG5FqRSwslfB693*iGt5jLeYq&N-V>gyNPx+n3iCFy#4 ze{=)PRV1xO9QARNGAJ1d?Nejub?6p&qc@>5phn_D-t&?9tdDS;4V1s8T2B_YJVy4$ zHz%U@nnhkGKcY3GFY|^g`M0^EZD{sb+{#(8oZFEDS)WVu_p^?%743B@EFB>nipS+L zBTYMYMC9GOz+I219(~^LdjE<9n~M0EWZ8+Hlx&DkS`8squp$55THRTgH+-IP;}j(V9t%ATX8uet3mVpcI7BtKry*L?r0 zVBU}Z&H0N6`hRejFHi zMYnpAdXSx~s-EMg9IBJ!S(TzbruJhMN&P3dP2SV+Q5Y@XVL?2V4zD>cRe6DQFXLl5 z_?wkp`Gq+5ns`<^3Y>1!Tpir&o&Jx#pT-A#8N;QPWNhN@F`7A_PyytO6sLOM2G(3knQ z*SoULZaV{UPCkj~7sG-ICt`fc8i}x2qAuPTzGV4t&v_P`8r}=|Xyv zx_nN~y?`(B2P>Uty6@qBuKv7f^*PsRLS+_6_ilx_@Rwt6TIH)ZL~$ZigJ_kuymclC zJ@1><>hr4WmH0s;c1oVkKe~ONl%nIXMeH-F_QSai!%6aQ#u(tg+DLH zhS!>=xRdAzp`B&YT}eVoFFXyuX&tq*S##Fm`MR6o@0ZM*`XQb z;gaW7@R8GrQma^;@aThx{?zyQt#O`p-5UPHD$U&RxbhvcQ+?JrlzY+&`QCQT Date: Tue, 16 Aug 2016 09:25:29 -0500 Subject: [PATCH 09/13] Made requested changes. --- DSCResources/Helper.psm1 | 64 +++ .../MSFT_GPInheritance.psm1 | 151 ++++--- .../MSFT_GPInheritance.schema.mof | 8 +- .../MSFT_GPOImport/MSFT_GPOImport.psm1 | 183 ++++++-- .../MSFT_GPOImport/MSFT_GPOImport.schema.mof | 16 +- DSCResources/MSFT_GPOLink/MSFT_GPOLink.psm1 | 394 ++++++++++++------ .../MSFT_GPOLink/MSFT_GPOLink.schema.mof | 18 +- GroupPolicyDsc.psd1 | Bin 6676 -> 6738 bytes README.md | 65 ++- .../MSFT_GPInheritance.Integration.tests.ps1 | 5 - .../Integration/MSFT_GPInheritance.config.ps1 | 2 +- .../MSFT_GPOImport.Integration.tests.ps1 | 5 - Tests/Integration/MSFT_GPOImport.config.ps1 | 2 +- .../MSFT_GPOLink.Integration.tests.ps1 | 5 - Tests/Integration/MSFT_GPOLink.config.ps1 | 2 +- Tests/Unit/MSFT_GPInheritance.Tests.ps1 | 12 +- appveyor.yml | 13 +- 17 files changed, 639 insertions(+), 306 deletions(-) create mode 100644 DSCResources/Helper.psm1 diff --git a/DSCResources/Helper.psm1 b/DSCResources/Helper.psm1 new file mode 100644 index 0000000..ff5d728 --- /dev/null +++ b/DSCResources/Helper.psm1 @@ -0,0 +1,64 @@ +<# + .SYNOPSIS + Tests the $Target parameter to ensure it contains the RootDSE and adds it if it doesn't. + + .PARAMETER Target + The target OU Distinguished Name with or without the RootDSE. + + .PARAMETER Domain + Not used. Included to allow @PSBoundParameters in function call. + + .PARAMETER Server + The name of the server. Optional. + + .PARAMETER Ensure + Not used. Included to allow @PSBoundParameters in function call. + +#> +function Test-TargetDN +{ + param + ( + [parameter(Mandatory = $true)] + [string] + $Target, + + [string] + $Domain, + + [string] + $Server, + + [ValidateSet('Present','Absent')] + [string] + $Ensure = 'Present' + ) + + $getADDomainParams = @{} + if ($Server) + { + $getADDomainParams += @{ + Server = $Server + } + } + Write-Verbose -Message ("Checking the Domain Distinguished Name is " + + "present on the Target Distinguished Name.") + $domainDN = (Get-ADDomain @getADDomainParams).DistinguishedName + if ($Target -like "*$domainDN") + { + Write-Verbose -Message "Target has full DN." + } + else + { + Write-Verbose -Message "Adding the Domain Distinguished Name to the Target DN." + if ($Target.EndsWith(",")) + { + $Target = "$Target$domainDN" + } + else + { + $Target = "$Target,$domainDN" + } + } + Write-Output -InputObject $Target +} diff --git a/DSCResources/MSFT_GPInheritance/MSFT_GPInheritance.psm1 b/DSCResources/MSFT_GPInheritance/MSFT_GPInheritance.psm1 index 8bafaef..e6213d3 100644 --- a/DSCResources/MSFT_GPInheritance/MSFT_GPInheritance.psm1 +++ b/DSCResources/MSFT_GPInheritance/MSFT_GPInheritance.psm1 @@ -4,12 +4,22 @@ param ( [parameter(Mandatory = $true)] - [string]$Target, - [string]$Domain, - [string]$Server, + [string] + $Target, + + [string] + $Domain, + + [string] + $Server, + [ValidateSet('Present','Absent')] - [string]$Ensure = 'Present' + [string] + $Ensure = 'Present' ) + + Import-Module $PSScriptRoot\..\Helper.psm1 -Verbose:$false + Import-Module -Name GroupPolicy -Verbose:$false $Target = Test-TargetDN @PSBoundParameters $targetResource = @{ Target = $Target @@ -17,23 +27,34 @@ Server = $null Ensure = $null } - $params = @{Target = $Target} + $getGPInheritanceParams = @{ + Target = $Target + } if ($Domain) { $targetResource.Domain = $Domain - $params += @{Domain = $Domain} + $getGPInheritanceParams += @{ + Domain = $Domain + } } if ($Server) { $targetResource.Server = $Server - $params += @{Server = $Server} + $getGPInheritanceParams += @{ + Server = $Server + } } - Import-Module GroupPolicy -Verbose:$false - Write-Verbose 'Getting Group Policy Inheritance' - $gpoInheritanceBlocked = (Get-GPInheritance @params).GpoInheritanceBlocked - if (!$gpoInheritanceBlocked) {$targetResource.Ensure = 'Present'} - else {$targetResource.Ensure = 'Absent'} - Write-Output $targetResource + Write-Verbose -Message 'Getting Group Policy Inheritance' + $gpoInheritanceBlocked = (Get-GPInheritance @getGPInheritanceParams).GpoInheritanceBlocked + if (!$gpoInheritanceBlocked) + { + $targetResource.Ensure = 'Present' + } + else + { + $targetResource.Ensure = 'Absent' + } + Write-Output -InputObject $targetResource } function Set-TargetResource @@ -41,37 +62,49 @@ function Set-TargetResource param ( [parameter(Mandatory = $true)] - [string]$Target, - [string]$Domain, - [string]$Server, + [string] + $Target, + + [string] + $Domain, + + [string] + $Server, + [ValidateSet('Present','Absent')] - [string]$Ensure = 'Present' + [string] + $Ensure = 'Present' ) + if ($Ensure -eq 'Present') { - Write-Verbose 'Enabling Group Policy Inheritance' + Write-Verbose -Message 'Enabling Group Policy Inheritance' $isBlocked = 'No' } else { - Write-Verbose 'Disabling Group Policy Inheritance' + Write-Verbose -Message 'Disabling Group Policy Inheritance' $isBlocked = 'Yes' } $Target = Test-TargetDN @PSBoundParameters - $params = @{ + $setGPInheritanceParams = @{ Target = $Target IsBlocked = $IsBlocked } if ($Domain) { - $params += @{Domain = $Domain} + $setGPInheritanceParams += @{ + Domain = $Domain + } } if ($Server) { - $params += @{Server = $Server} + $setGPInheritanceParams += @{ + Server = $Server + } } - Import-Module GroupPolicy -Verbose:$false - $null = Set-GPInheritance @params + Import-Module -Name GroupPolicy -Verbose:$false + $null = Set-GPInheritance @setGPInheritanceParams } function Test-TargetResource @@ -80,58 +113,44 @@ function Test-TargetResource param ( [parameter(Mandatory = $true)] - [string]$Target, - [string]$Domain, - [string]$Server, + [string] + $Target, + + [string] + $Domain, + + [string] + $Server, + [ValidateSet('Present','Absent')] - [string]$Ensure = 'Present' + [string] + $Ensure = 'Present' ) + $targetResource = Get-TargetResource @PSBoundParameters switch ($Ensure) { Present { - if ($targetResource.Ensure -eq 'Present') {$true} - else {$false} + if ($targetResource.Ensure -eq 'Present') + { + Write-Output -InputObject $true + } + else + { + Write-Output -InputObject $false + } } Absent { - if ($targetResource.Ensure -eq 'Absent') {$true} - else {$false} - } - } -} - -function Test-TargetDN -{ - param - ( - [parameter(Mandatory = $true)] - [string]$Target, - [string]$Domain, - [string]$Server, - [ValidateSet('Present','Absent')] - [string]$Ensure = 'Present' - ) - $params = @{} - if ($Server) {$params += @{Server = $Server}} - Write-Verbose "Checking the Domain Distinguished Name is present on the Target Distinguished Name." - $domainDN = (Get-ADDomain @params).DistinguishedName - if ($Target -like "*$domainDN") - { - Write-Verbose "Target has full DN." - } - else - { - Write-Verbose "Adding the Domain Distinguished Name to the Target DN." - if ($Target.EndsWith(",")) - { - $Target = "$Target$domainDN" - } - else - { - $Target = "$Target,$domainDN" + if ($targetResource.Ensure -eq 'Absent') + { + Write-Output -InputObject $true + } + else + { + Write-Output -InputObject $false + } } } - $Target } diff --git a/DSCResources/MSFT_GPInheritance/MSFT_GPInheritance.schema.mof b/DSCResources/MSFT_GPInheritance/MSFT_GPInheritance.schema.mof index be3217b..3e79c7f 100644 --- a/DSCResources/MSFT_GPInheritance/MSFT_GPInheritance.schema.mof +++ b/DSCResources/MSFT_GPInheritance/MSFT_GPInheritance.schema.mof @@ -1,8 +1,8 @@ [ClassVersion("1.0.0"), FriendlyName("GPInheritance")] class MSFT_GPInheritance : OMI_BaseResource { - [Key] String Target; - [write] String Domain; - [write] String Server; - [write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] string Ensure; + [Key] String Target; + [write] String Domain; + [write] String Server; + [write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] string Ensure; }; diff --git a/DSCResources/MSFT_GPOImport/MSFT_GPOImport.psm1 b/DSCResources/MSFT_GPOImport/MSFT_GPOImport.psm1 index c7c50e4..f0f8003 100644 --- a/DSCResources/MSFT_GPOImport/MSFT_GPOImport.psm1 +++ b/DSCResources/MSFT_GPOImport/MSFT_GPOImport.psm1 @@ -4,28 +4,54 @@ param ( [parameter(Mandatory = $true)] - [string]$TargetName, + [string] + $TargetName, + [parameter(Mandatory = $true)] - [string]$Path, + [string] + $Path, + [parameter(Mandatory = $true)] - [string]$BackupIdentity, + [string] + $BackupIdentity, + [ValidateSet('Name','Guid')] - [string]$BackupIdentityType = 'Name', - [string]$Domain, - [string]$MigrationTable, - [string]$Server, + [string] + $BackupIdentityType = 'Name', + + [string] + $Domain, + + [string] + $MigrationTable, + + [string] + $Server, + [ValidateSet('Present')] - [string]$Ensure = 'Present' + [string] + $Ensure = 'Present' ) - Import-Module GroupPolicy -Verbose:$false - $params = @{ + + Import-Module -Name GroupPolicy -Verbose:$false + $getGPOParams = @{ Name = $TargetName ErrorAction = 'SilentlyContinue' } - if ($Domain) {$params += @{Domain = $Domain}} - if ($Server) {$params += @{Server = $Server}} - Write-Verbose 'Getting GPO' - $gpo = Get-GPO @params + if ($Domain) + { + $getGPOParams += @{ + Domain = $Domain + } + } + if ($Server) + { + $getGPOParams += @{ + Server = $Server + } + } + Write-Verbose -Message 'Getting GPO' + $gpo = Get-GPO @getGPOParams $targetResource = @{ TargetName = $TargetName Path = $Path @@ -36,14 +62,20 @@ Server = $null Ensure = 'Absent' } - if ($MigrationTable) {$targetResource.MigrationTable = $MigrationTable} - if ($Server) {$targetResource.Server = $Server} + if ($MigrationTable) + { + $targetResource.MigrationTable = $MigrationTable + } + if ($Server) + { + $targetResource.Server = $Server + } if ($gpo) { $targetResource.Domain = $gpo.DomainName $targetResource.Ensure = 'Present' } - $targetResource + Write-Output -InputObject $targetResource } function Set-TargetResource @@ -51,32 +83,73 @@ function Set-TargetResource param ( [parameter(Mandatory = $true)] - [string]$TargetName, + [string] + $TargetName, + [parameter(Mandatory = $true)] - [string]$Path, + [string] + $Path, + [parameter(Mandatory = $true)] - [string]$BackupIdentity, + [string] + $BackupIdentity, + [ValidateSet('Name','Guid')] - [string]$BackupIdentityType = 'Name', - [string]$Domain, - [string]$MigrationTable, - [string]$Server, + [string] + $BackupIdentityType = 'Name', + + [string] + $Domain, + + [string] + $MigrationTable, + + [string] + $Server, + [ValidateSet('Present')] - [string]$Ensure = 'Present' + [string] + $Ensure = 'Present' ) - Import-Module GroupPolicy -Verbose:$false - $params = @{ + + Import-Module -Name GroupPolicy -Verbose:$false + $importGPOParams = @{ TargetName = $TargetName Path = $Path CreateIfNeeded = $true } - if ($BackupIdentityType -eq 'Name') {$params += @{BackupGpoName = $BackupIdentity}} - else {$params += @{BackupId = $BackupIdentity}} - if ($Domain) {$params += @{Domain = $Domain}} - if ($MigrationTable) {$params += @{MigrationTable = $MigrationTable}} - if ($Server) {$params += @{Server = $Server}} - Write-Verbose 'Importing GPO' - $null = Import-GPO @params + if ($BackupIdentityType -eq 'Name') + { + $importGPOParams += @{ + BackupGpoName = $BackupIdentity + } + } + else + { + $importGPOParams += @{ + BackupId = $BackupIdentity + } + } + if ($Domain) + { + $importGPOParams += @{ + Domain = $Domain + } + } + if ($MigrationTable) + { + $importGPOParams += @{ + MigrationTable = $MigrationTable + } + } + if ($Server) + { + $importGPOParams += @{ + Server = $Server + } + } + Write-Verbose -Message 'Importing GPO' + $null = Import-GPO @importGPOParams } function Test-TargetResource @@ -85,20 +158,42 @@ function Test-TargetResource param ( [parameter(Mandatory = $true)] - [string]$TargetName, + [string] + $TargetName, + [parameter(Mandatory = $true)] - [string]$Path, + [string] + $Path, + [parameter(Mandatory = $true)] - [string]$BackupIdentity, + [string] + $BackupIdentity, + [ValidateSet('Name','Guid')] - [string]$BackupIdentityType = 'Name', - [string]$Domain, - [string]$MigrationTable, - [string]$Server, + [string] + $BackupIdentityType = 'Name', + + [string] + $Domain, + + [string] + $MigrationTable, + + [string] + $Server, + [ValidateSet('Present')] - [string]$Ensure = 'Present' + [string] + $Ensure = 'Present' ) + $targetResource = Get-TargetResource @PSBoundParameters - if ($targetResource.Ensure -eq 'Present') {$true} - else {$false} + if ($targetResource.Ensure -eq 'Present') + { + Write-Output -InputObject $true + } + else + { + Write-Output -InputObject $false + } } diff --git a/DSCResources/MSFT_GPOImport/MSFT_GPOImport.schema.mof b/DSCResources/MSFT_GPOImport/MSFT_GPOImport.schema.mof index 9c49d47..713bb7d 100644 --- a/DSCResources/MSFT_GPOImport/MSFT_GPOImport.schema.mof +++ b/DSCResources/MSFT_GPOImport/MSFT_GPOImport.schema.mof @@ -1,12 +1,12 @@ [ClassVersion("1.0.0"), FriendlyName("GPOImport")] class MSFT_GPOImport : OMI_BaseResource { - [Key] String TargetName; - [required] String Path; - [required] String BackupIdentity; - [write,ValueMap{"Name", "Guid"},Values{"Name", "Guid"}] string BackupIdentityType; - [write] String Domain; - [write] String MigrationTable; - [write] String Server; - [write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] string Ensure; + [Key] String TargetName; + [required] String Path; + [required] String BackupIdentity; + [write,ValueMap{"Name", "Guid"},Values{"Name", "Guid"}] string BackupIdentityType; + [write] String Domain; + [write] String MigrationTable; + [write] String Server; + [write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] string Ensure; }; diff --git a/DSCResources/MSFT_GPOLink/MSFT_GPOLink.psm1 b/DSCResources/MSFT_GPOLink/MSFT_GPOLink.psm1 index f5a77a4..8f987dd 100644 --- a/DSCResources/MSFT_GPOLink/MSFT_GPOLink.psm1 +++ b/DSCResources/MSFT_GPOLink/MSFT_GPOLink.psm1 @@ -3,29 +3,58 @@ param ( [parameter(Mandatory = $true)] - [string]$Identity, + [string] + $Identity, + [ValidateSet('Name','Guid')] - [string]$IdentityType = 'Name', + [string] + $IdentityType = 'Name', + [parameter(Mandatory = $true)] - [string]$Target, - [string]$Domain, + [string] + $Target, + + [string] + $Domain, + [ValidateSet('Yes','No')] - [string]$Enforced, + [string] + $Enforced, + [ValidateSet('Yes','No')] - [string]$LinkEnabled, - [int16]$Order, - [string]$Server, + [string] + $LinkEnabled, + + [int16] + $Order, + + [string] + $Server, + [ValidateSet('Present','Absent')] - [string]$Ensure = 'Present' + [string] + $Ensure = 'Present' ) + + Import-Module $PSScriptRoot\..\Helper.psm1 -Verbose:$false + Import-Module -Name GroupPolicy -Verbose:$false $target = Test-TargetDN @PSBoundParameters $gpInheritanceparams = @{ Target = $target } - if ($Server) {$gpInheritanceparams += @{Server = $Server}} - if ($Domain) {$gpInheritanceparams += @{Domain = $Domain}} - Import-Module GroupPolicy -Verbose:$false - Write-Verbose 'Getting GPO Links' + if ($Server) + { + $gpInheritanceparams += @{ + Server = $Server + } + } + if ($Domain) + { + $gpInheritanceparams += @{ + Domain = $Domain + } + } + Write-Verbose -Message 'Getting GPO Links' $gpoLinks = (Get-GPInheritance @gpInheritanceparams).GpoLinks $gpo = Get-GpoInfo @PSBoundParameters $targetResource = @{ @@ -41,111 +70,227 @@ } if ($gpo) { - # Using the GpoId attribute of the GPO Links instead of the - # Name attribute because the Name attribute may take a while - # to replicate to all DCs if the GPO was recently created. - $targetLink = $gpoLinks | where {$_.GpoId -eq $gpo.Id} + <# + Using the GpoId attribute of the GPO Links instead of the + Name attribute because the Name attribute may take a while + to replicate to all DCs if the GPO was recently created. + #> + $targetLink = $gpoLinks | Where-Object {$_.GpoId -eq $gpo.Id} if ($targetLink) { - if ($targetLink.Enabled) {$targetResource.LinkEnabled = 'Yes'} - else {$targetResource.LinkEnabled = 'No'} - if ($targetLink.Enforced) {$targetResource.Enforced = 'Yes'} - else {$targetResource.Enforced = 'No'} + if ($targetLink.Enabled) + { + $targetResource.LinkEnabled = 'Yes' + } + else + { + $targetResource.LinkEnabled = 'No' + } + if ($targetLink.Enforced) + { + $targetResource.Enforced = 'Yes' + } + else + { + $targetResource.Enforced = 'No' + } $targetResource.Order = $targetLink.Order $targetResource.Ensure = 'Present' } $targetResource.Domain = $gpo.DomainName } - $targetResource + Write-Output -InputObject $targetResource } function Set-TargetResource { param ( [parameter(Mandatory = $true)] - [string]$Identity, + [string] + $Identity, + [ValidateSet('Name','Guid')] - [string]$IdentityType = 'Name', + [string] + $IdentityType = 'Name', + [parameter(Mandatory = $true)] - [string]$Target, - [string]$Domain, + [string] + $Target, + + [string] + $Domain, + [ValidateSet('Yes','No')] - [string]$Enforced, + [string] + $Enforced, + [ValidateSet('Yes','No')] - [string]$LinkEnabled, - [int16]$Order, - [string]$Server, + [string] + $LinkEnabled, + + [int16] + $Order, + + [string] + $Server, + [ValidateSet('Present','Absent')] - [string]$Ensure = 'Present' + [string] + $Ensure = 'Present' ) - Import-Module GroupPolicy -Verbose:$false + + Import-Module -Name GroupPolicy -Verbose:$false $targetResource = Get-TargetResource @PSBoundParameters $gpo = Get-GpoInfo @PSBoundParameters if ($Ensure -eq 'Present') { if ($targetResource.Ensure -eq 'Present') { - $setParams = @{Target = $targetResource.Target} + $setGPLinkParams = @{ + Target = $targetResource.Target + } if ($IdentityType -eq 'Name') { - # Using the GpoId attribute of the GPO Links instead of the - # Name attribute because the Name attribute may take a while - # to replicate to all DCs if the GPO was recently created. - $setParams += @{Guid = $gpo.Id} + <# + Using the GpoId attribute of the GPO Links instead of the + Name attribute because the Name attribute may take a while + to replicate to all DCs if the GPO was recently created. + #> + $setGPLinkParams += @{ + Guid = $gpo.Id + } + } + else + { + $setGPLinkParams += @{ + Guid = $Identity + } + } + if ($Domain) + { + $setGPLinkParams += @{ + Domain = $Domain + } } - else {$setParams += @{Guid = $Identity}} - if ($Domain) {$setParams += @{Domain = $Domain}} if ($Enforced -and $targetResource.Enforced -ne $Enforced) { - $setParams += @{Enforced = $Enforced} + $setGPLinkParams += @{ + Enforced = $Enforced + } } if ($LinkEnabled -and $targetResource.LinkEnabled -ne $LinkEnabled) { - $setParams += @{LinkEnabled = $LinkEnabled} + $setGPLinkParams += @{ + LinkEnabled = $LinkEnabled + } } if ($Order -and $targetResource.Order -ne $Order) { - $setParams += @{Order = $Order} + $setGPLinkParams += @{ + Order = $Order + } + } + if ($Server) + { + $setGPLinkParams += @{ + Server = $Server + } } - if ($Server) {$setParams += @{Server = $Server}} - Write-Verbose 'Updating GPO Link' - Set-GPLink @setParams + Write-Verbose -Message 'Updating GPO Link' + Set-GPLink @setGPLinkParams } else { - $newParams = @{Target = $targetResource.Target} + $newGPLinkParams = @{ + Target = $targetResource.Target + } if ($IdentityType -eq 'Name') { - # Using the GpoId attribute of the GPO Links instead of the - # Name attribute because the Name attribute may take a while - # to replicate to all DCs if the GPO was recently created. - $newParams += @{Guid = $gpo.Id} + <# + Using the GpoId attribute of the GPO Links instead of the + Name attribute because the Name attribute may take a while + to replicate to all DCs if the GPO was recently created. + #> + $newGPLinkParams += @{ + Guid = $gpo.Id + } + } + else + { + $newGPLinkParams += @{ + Guid = $Identity + } + } + if ($Domain) + { + $newGPLinkParams += @{ + Domain = $Domain + } + } + if ($Enforced) + { + $newGPLinkParams += @{ + Enforced = $Enforced + } + } + if ($LinkEnabled) + { + $newGPLinkParams += @{ + LinkEnabled = $LinkEnabled + } + } + if ($Order) + { + $newGPLinkParams += @{ + Order = $Order + } + } + if ($Server) + { + $newGPLinkParams += @{ + Server = $Server + } } - else {$newParams += @{Guid = $Identity}} - if ($Domain) {$newParams += @{Domain = $Domain}} - if ($Enforced) {$newParams += @{Enforced = $Enforced}} - if ($LinkEnabled) {$newParams += @{LinkEnabled = $LinkEnabled}} - if ($Order) {$newParams += @{Order = $Order}} - if ($Server) {$newParams += @{Server = $Server}} - Write-Verbose 'Creating GPO Link' - New-GPLink @newParams + Write-Verbose -Message 'Creating GPO Link' + New-GPLink @newGPLinkParams } } else { - $removeParams = @{Target = $targetResource.Target} + $removeGPLinkParams = @{ + Target = $targetResource.Target + } if ($IdentityType -eq 'Name') { - # Using the GpoId attribute of the GPO Links instead of the - # Name attribute because the Name attribute may take a while - # to replicate to all DCs if the GPO was recently created. - $removeParams += @{Guid = $gpo.Id} + <# + Using the GpoId attribute of the GPO Links instead of the + Name attribute because the Name attribute may take a while + to replicate to all DCs if the GPO was recently created. + #> + $removeGPLinkParams += @{ + Guid = $gpo.Id + } + } + else + { + $removeGPLinkParams += @{ + Guid = $Identity + } + } + if ($Domain) + { + $removeGPLinkParams += @{ + Domain = $Domain + } } - else {$removeParams += @{Guid = $Identity}} - if ($Domain) {$removeParams += @{Domain = $Domain}} - if ($Server) {$removeParams += @{Server = $Server}} - Write-Verbose 'Removing GPO Link' - Remove-GPLink @removeParams + if ($Server) + { + $removeGPLinkParams += @{ + Server = $Server + } + } + Write-Verbose -Message 'Removing GPO Link' + Remove-GPLink @removeGPLinkParams } } @@ -154,21 +299,39 @@ function Test-TargetResource { param ( [parameter(Mandatory = $true)] - [string]$Identity, + [string] + $Identity, + [ValidateSet('Name','Guid')] - [string]$IdentityType = 'Name', + [string] + $IdentityType = 'Name', + [parameter(Mandatory = $true)] - [string]$Target, - [string]$Domain, + [string] + $Target, + + [string] + $Domain, + [ValidateSet('Yes','No')] - [string]$Enforced, + [string] + $Enforced, + [ValidateSet('Yes','No')] - [string]$LinkEnabled, - [int16]$Order, - [string]$Server, + [string] + $LinkEnabled, + + [int16] + $Order, + + [string] + $Server, + [ValidateSet('Present','Absent')] - [string]$Ensure = 'Present' + [string] + $Ensure = 'Present' ) + $targetResource = Get-TargetResource @PSBoundParameters $targetResourceInCompliance = $true if ($Ensure -eq 'Present') @@ -188,16 +351,19 @@ function Test-TargetResource { $targetResourceInCompliance = $false } } - else {$targetResourceInCompliance = $false} + else + { + $targetResourceInCompliance = $false + } } elseif ($targetResource.Ensure -eq 'Present') { $targetResourceInCompliance = $false } - $targetResourceInCompliance + Write-Output -InputObject $targetResourceInCompliance } -function Test-TargetDN +function Get-GpoInfo { param ( @@ -217,61 +383,33 @@ function Test-TargetDN [ValidateSet('Present','Absent')] [string]$Ensure = 'Present' ) - $params = @{} - if ($Server) {$params += @{Server = $Server}} - Write-Verbose "Checking the Domain Distinguished Name is present on the Target Distinguished Name." - $domainDN = (Get-ADDomain @params).DistinguishedName - if ($Target -like "*$domainDN") + + Import-Module -Name GroupPolicy -Verbose:$false + $getGPOParams = @{} + if ($Server) { - Write-Verbose "Target has full DN." + $getGPOParams += @{ + Server = $Server + } } - else + if ($Domain) { - Write-Verbose "Adding the Domain Distinguished Name to the Target DN." - if ($Target.EndsWith(",")) - { - $Target = "$Target$domainDN" - } - else - { - $Target = "$Target,$domainDN" + $getGPOParams += @{ + Domain = $Domain } } - $Target -} - -function Get-GpoInfo -{ - param - ( - [parameter(Mandatory = $true)] - [string]$Identity, - [ValidateSet('Name','Guid')] - [string]$IdentityType = 'Name', - [parameter(Mandatory = $true)] - [string]$Target, - [string]$Domain, - [ValidateSet('Yes','No')] - [string]$Enforced, - [ValidateSet('Yes','No')] - [string]$LinkEnabled, - [int16]$Order, - [string]$Server, - [ValidateSet('Present','Absent')] - [string]$Ensure = 'Present' - ) - $gpoParams = @{} - if ($Server) + if ($IdentityType -eq 'Name') { - $gpoParams += @{Server = $Server} + $getGPOParams += @{ + Name = $Identity + } } - if ($Domain) + else { - $gpoParams += @{Domain = $Domain} + $getGPOParams += @{ + Guid = $Identity + } } - if ($IdentityType -eq 'Name') {$gpoParams += @{Name = $Identity}} - else {$gpoParams += @{Guid = $Identity}} - Import-Module GroupPolicy -Verbose:$false - Write-Verbose 'Getting GPO' - Get-GPO @gpoParams + Write-Verbose -Message 'Getting GPO' + Get-GPO @getGPOParams } diff --git a/DSCResources/MSFT_GPOLink/MSFT_GPOLink.schema.mof b/DSCResources/MSFT_GPOLink/MSFT_GPOLink.schema.mof index 8cf3706..f0f81ba 100644 --- a/DSCResources/MSFT_GPOLink/MSFT_GPOLink.schema.mof +++ b/DSCResources/MSFT_GPOLink/MSFT_GPOLink.schema.mof @@ -1,13 +1,13 @@ [ClassVersion("1.0.0"), FriendlyName("GPOLink")] class MSFT_GPOLink : OMI_BaseResource { - [Key] String Identity; - [Write,ValueMap{"Name", "Guid"},Values{"Name", "Guid"}] String IdentityType; - [Key] String Target; - [Write] String Domain; - [Write,ValueMap{"Yes", "No"},Values{"Yes", "No"}] String Enforced; - [Write,ValueMap{"Yes", "No"},Values{"Yes", "No"}] String LinkEnabled; - [Write] Sint16 Order; - [Write] String Server; - [Write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] String Ensure; + [Key] String Identity; + [Write,ValueMap{"Name", "Guid"},Values{"Name", "Guid"}] String IdentityType; + [Key] String Target; + [Write] String Domain; + [Write,ValueMap{"Yes", "No"},Values{"Yes", "No"}] String Enforced; + [Write,ValueMap{"Yes", "No"},Values{"Yes", "No"}] String LinkEnabled; + [Write] Sint16 Order; + [Write] String Server; + [Write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] String Ensure; }; diff --git a/GroupPolicyDsc.psd1 b/GroupPolicyDsc.psd1 index 0056ccb135743af16c6998cf3c7061831720f25b..6622f83305d055963a4935cd7fe36f1ea8e955d9 100644 GIT binary patch delta 159 zcmbPYa>-8mPGcxxP+)KdvWgfAz+@s&BooNW Yn{3EjNRn#d$v2pbh}W?>nq{Xb0MkArO#lD@ delta 101 zcmca)GR0(r7}I7sCN4%nXNG)+B8Ex^1%_}SE1w}{av*b|vL8b#LkUAVLn1>aLmp5r i1jtWj$N;kQ8FGL)ouLw_PI&S^<|0fJHqT_)DGC6j;uqck diff --git a/README.md b/README.md index ae44cf7..84b1685 100644 --- a/README.md +++ b/README.md @@ -4,44 +4,71 @@ The **GroupPolicyDsc** module contains DSC resources for configuring Group Policy. -## Contributing -Please check out common DSC Resources [contributing guidelines](https://github.com/PowerShell/DscResource.Kit/blob/master/CONTRIBUTING.md). +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. + +## How to Contribute +If you would like to contribute to this repository, please read the DSC Resource Kit [contributing guidelines](https://github.com/PowerShell/DscResource.Kit/blob/master/CONTRIBUTING.md). ## Resources * **GPInheritance** blocks or unblocks inheritance for a specified domain or organizational unit (OU). -* **GPOImport** imports the Group Policy settings from a backed-up GPO into a new GPO. It won't import settings into an existing GPO. +* **GPOImport** imports the Group Policy settings from a backed-up GPO into a new GPO. +It won't import settings into an existing GPO. * **GPOLink** links a GPO to a site, domain, or organizational unit (OU). ### GPInheritance -* **Target**: Specifies the domain or the OU for which to block or unblock inheritance by its LDAP distinguished name. You can also leave off the domain part of the distinguished name and it will be generated automatically. See the example below. -* **Domain**: Optional. Specifies the domain to run against. -* **Server**: Optional. Specifies the name of the domain controller that this resource contacts to complete the operation. You can specify either the fully qualified domain name (FQDN) or the host name. -* **Ensure**: Whether inheritance should be blocked (Absent) or unblocked (Present). Defaults to Present. +* **Target**: Specifies the domain or the OU for which to block or unblock inheritance by its LDAP distinguished name. +You can also leave off the domain part of the distinguished name and it will be generated automatically. +See the UnblockInheritance.ps1 example in the Examples folder. +* **Domain**: Specifies the domain to run against. +Optional. +* **Server**: Specifies the name of the domain controller that this resource contacts to complete the operation. +You can specify either the fully qualified domain name (FQDN) or the host name. +Optional. +* **Ensure**: Whether inheritance should be blocked (Absent) or unblocked (Present). +Defaults to Present. ### GPOImport * **TargetName**: Specifies the display name of the GPO into which the settings are to be imported. * **Path**: Specifies the path to the backup directory. * **BackupIdentity**: Specifies the display name or backup ID of the backed-up GPO from which to import the settings. -* **BackupIdentityType**: Specifies the type of the BackupIdentity (Name or Guid). Defaults to Name. -* **Domain**: Optional. Specifies the domain to run against. +* **BackupIdentityType**: Specifies the type of the BackupIdentity (Name or Guid). +Defaults to Name. +* **Domain**: Specifies the domain to run against. +Optional. * **MigrationTable**: Specifies the path to a migration table file. -* **Server**: Optional. Specifies the name of the domain controller that this resource contacts to complete the operation. You can specify either the fully qualified domain name (FQDN) or the host name. -* **Ensure**: Must be Present. Defaults to Present. +* **Server**: Specifies the name of the domain controller that this resource contacts to complete the operation. +You can specify either the fully qualified domain name (FQDN) or the host name. +Optional. +* **Ensure**: Must be Present. +Defaults to Present. ### GPOLink * **Identity**: Specifies the GPO to link by its display name or GUID. -* **IdentityType**: Specifies the type of the Identity (Name or Guid). Defaults to Name. -* **Target**: Specifies the LDAP distinguished name of the site, domain, or OU to which to link the GPO. You can also leave off the domain part of the distinguished name and it will be generated automatically. See the example below. -* **Domain**: Optional. Specifies the domain to run against. -* **Enforced**: Specifies whether the GPO link is enforced. You can specify Yes or No. Defaults to No. -* **LinkEnabled**: Specifies whether the GPO link is enabled. You can specify Yes or No. Defaults to Yes. -* **Order**: Specifies the link order for the GPO link. You can specify a number that is between one and the current number of GPO links to the target site, domain, or OU, plus one. -* **Server**: Optional. Specifies the name of the domain controller that this resource contacts to complete the operation. You can specify either the fully qualified domain name (FQDN) or the host name. -* **Ensure**: Whether the GPO Link should exist (Present) or not (Absent). Defaults to Present. +* **IdentityType**: Specifies the type of the Identity (Name or Guid). +Defaults to Name. +* **Target**: Specifies the LDAP distinguished name of the site, domain, or OU to which to link the GPO. +You can also leave off the domain part of the distinguished name and it will be generated automatically. +See the GpoLinkByGuidAndDisable.ps1 example in the Examples folder. +* **Domain**: Specifies the domain to run against. +Optional. +* **Enforced**: Specifies whether the GPO link is enforced. +You can specify Yes or No. +Defaults to No. +* **LinkEnabled**: Specifies whether the GPO link is enabled. +You can specify Yes or No. +Defaults to Yes. +* **Order**: Specifies the link order for the GPO link. +You can specify a number that is between one and the current number of GPO links to the target site, domain, or OU, plus one. +* **Server**: Specifies the name of the domain controller that this resource contacts to complete the operation. +You can specify either the fully qualified domain name (FQDN) or the host name. +Optional. +* **Ensure**: Whether the GPO Link should exist (Present) or not (Absent). +Defaults to Present. ## Versions diff --git a/Tests/Integration/MSFT_GPInheritance.Integration.tests.ps1 b/Tests/Integration/MSFT_GPInheritance.Integration.tests.ps1 index e443616..18a3574 100644 --- a/Tests/Integration/MSFT_GPInheritance.Integration.tests.ps1 +++ b/Tests/Integration/MSFT_GPInheritance.Integration.tests.ps1 @@ -1,6 +1,5 @@ $Global:DSCModuleName = 'GroupPolicyDsc' $Global:DSCResourceName = 'MSFT_GPInheritance' -# /TODO #region HEADER [String] $moduleRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $Script:MyInvocation.MyCommand.Path)) @@ -20,8 +19,6 @@ $TestEnvironment = Initialize-TestEnvironment ` -TestType Integration #endregion -# TODO: Other Init Code Goes Here... - # Using try/finally to always cleanup even if something awful happens. try { @@ -59,6 +56,4 @@ finally #region FOOTER Restore-TestEnvironment -TestEnvironment $TestEnvironment #endregion - - # TODO: Other Optional Cleanup Code Goes Here... } diff --git a/Tests/Integration/MSFT_GPInheritance.config.ps1 b/Tests/Integration/MSFT_GPInheritance.config.ps1 index 5017dc3..843e2de 100644 --- a/Tests/Integration/MSFT_GPInheritance.config.ps1 +++ b/Tests/Integration/MSFT_GPInheritance.config.ps1 @@ -13,4 +13,4 @@ configuration 'MSFT_GPInheritance_config' { Ensure = $GPInheritance.Ensure } } -} \ No newline at end of file +} diff --git a/Tests/Integration/MSFT_GPOImport.Integration.tests.ps1 b/Tests/Integration/MSFT_GPOImport.Integration.tests.ps1 index 3da2a89..f87dca8 100644 --- a/Tests/Integration/MSFT_GPOImport.Integration.tests.ps1 +++ b/Tests/Integration/MSFT_GPOImport.Integration.tests.ps1 @@ -1,6 +1,5 @@ $Global:DSCModuleName = 'GroupPolicyDsc' $Global:DSCResourceName = 'MSFT_GPOImport' -# /TODO #region HEADER [String] $moduleRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $Script:MyInvocation.MyCommand.Path)) @@ -20,8 +19,6 @@ $TestEnvironment = Initialize-TestEnvironment ` -TestType Integration #endregion -# TODO: Other Init Code Goes Here... - # Using try/finally to always cleanup even if something awful happens. try { @@ -63,6 +60,4 @@ finally #region FOOTER Restore-TestEnvironment -TestEnvironment $TestEnvironment #endregion - - # TODO: Other Optional Cleanup Code Goes Here... } diff --git a/Tests/Integration/MSFT_GPOImport.config.ps1 b/Tests/Integration/MSFT_GPOImport.config.ps1 index 7c9c092..d511313 100644 --- a/Tests/Integration/MSFT_GPOImport.config.ps1 +++ b/Tests/Integration/MSFT_GPOImport.config.ps1 @@ -22,4 +22,4 @@ configuration 'MSFT_GPOImport_config' { Server = $GPO.Server } } -} \ No newline at end of file +} diff --git a/Tests/Integration/MSFT_GPOLink.Integration.tests.ps1 b/Tests/Integration/MSFT_GPOLink.Integration.tests.ps1 index e801b50..1567471 100644 --- a/Tests/Integration/MSFT_GPOLink.Integration.tests.ps1 +++ b/Tests/Integration/MSFT_GPOLink.Integration.tests.ps1 @@ -1,6 +1,5 @@ $Global:DSCModuleName = 'GroupPolicyDsc' $Global:DSCResourceName = 'MSFT_GPOLink' -# /TODO #region HEADER [String] $moduleRoot = Split-Path -Parent (Split-Path -Parent (Split-Path -Parent $Script:MyInvocation.MyCommand.Path)) @@ -20,8 +19,6 @@ $TestEnvironment = Initialize-TestEnvironment ` -TestType Integration #endregion -# TODO: Other Init Code Goes Here... - # Using try/finally to always cleanup even if something awful happens. try { @@ -63,6 +60,4 @@ finally #region FOOTER Restore-TestEnvironment -TestEnvironment $TestEnvironment #endregion - - # TODO: Other Optional Cleanup Code Goes Here... } diff --git a/Tests/Integration/MSFT_GPOLink.config.ps1 b/Tests/Integration/MSFT_GPOLink.config.ps1 index 586f39e..a931a61 100644 --- a/Tests/Integration/MSFT_GPOLink.config.ps1 +++ b/Tests/Integration/MSFT_GPOLink.config.ps1 @@ -20,4 +20,4 @@ configuration 'MSFT_GPOLink_config' { Ensure = $GPOLink.Ensure } } -} \ No newline at end of file +} diff --git a/Tests/Unit/MSFT_GPInheritance.Tests.ps1 b/Tests/Unit/MSFT_GPInheritance.Tests.ps1 index ec178da..41eaf58 100644 --- a/Tests/Unit/MSFT_GPInheritance.Tests.ps1 +++ b/Tests/Unit/MSFT_GPInheritance.Tests.ps1 @@ -50,9 +50,15 @@ try Server = 'localhost' Ensure = 'Absent' } - $fakeADDomain = @{DistinguishedName = $rootDSE} - $fakeGPInheritanceNotBlocked = @{GpoInheritanceBlocked = $false} - $fakeGPInheritanceBlocked = @{GpoInheritanceBlocked = $true} + $fakeADDomain = @{ + DistinguishedName = $rootDSE + } + $fakeGPInheritanceNotBlocked = @{ + GpoInheritanceBlocked = $false + } + $fakeGPInheritanceBlocked = @{ + GpoInheritanceBlocked = $true + } #endregion diff --git a/appveyor.yml b/appveyor.yml index 2b2d9e6..d6b90f7 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -7,13 +7,12 @@ # environment configuration # #---------------------------------# version: 1.0.{build}.0 -install: - - cinst -y pester - - git clone https://github.com/PowerShell/DscResource.Tests - - ps: Push-Location - - cd DscResource.Tests - - ps: Import-Module .\TestHelper.psm1 -force - - ps: Pop-Location +install: + - git clone https://github.com/PowerShell/DscResource.Tests + - ps: | + Import-Module -Name .\DscResource.Tests\TestHelper.psm1 -Force + Install-PackageProvider -Name NuGet -MinimumVersion 2.8.5.201 -Force + Install-Module -Name Pester -Repository PSGallery -Force #---------------------------------# # build configuration # From 21b5eddb97bae0868867df9a563a0d15379f5e80 Mon Sep 17 00:00:00 2001 From: Cory Wood Date: Thu, 25 Aug 2016 14:33:48 -0500 Subject: [PATCH 10/13] Made changes requested by TravisEz13. --- .../MSFT_GPInheritance.psm1 | 16 +-- .../MSFT_GPInheritance.schema.mof | 9 +- .../MSFT_GPOImport/MSFT_GPOImport.psm1 | 12 +- .../MSFT_GPOImport/MSFT_GPOImport.schema.mof | 17 +-- DSCResources/MSFT_GPOLink/MSFT_GPOLink.psm1 | 127 ++++++------------ .../MSFT_GPOLink/MSFT_GPOLink.schema.mof | 20 +-- README.md | 11 +- 7 files changed, 86 insertions(+), 126 deletions(-) diff --git a/DSCResources/MSFT_GPInheritance/MSFT_GPInheritance.psm1 b/DSCResources/MSFT_GPInheritance/MSFT_GPInheritance.psm1 index e6213d3..64ec555 100644 --- a/DSCResources/MSFT_GPInheritance/MSFT_GPInheritance.psm1 +++ b/DSCResources/MSFT_GPInheritance/MSFT_GPInheritance.psm1 @@ -5,7 +5,7 @@ ( [parameter(Mandatory = $true)] [string] - $Target, + $TargetDN, [string] $Domain, @@ -20,15 +20,15 @@ Import-Module $PSScriptRoot\..\Helper.psm1 -Verbose:$false Import-Module -Name GroupPolicy -Verbose:$false - $Target = Test-TargetDN @PSBoundParameters + $testTargetDN = Test-TargetDN @PSBoundParameters $targetResource = @{ - Target = $Target + TargetDN = $testTargetDN Domain = $null Server = $null Ensure = $null } $getGPInheritanceParams = @{ - Target = $Target + Target = $testTargetDN } if ($Domain) { @@ -63,7 +63,7 @@ function Set-TargetResource ( [parameter(Mandatory = $true)] [string] - $Target, + $TargetDN, [string] $Domain, @@ -86,9 +86,9 @@ function Set-TargetResource Write-Verbose -Message 'Disabling Group Policy Inheritance' $isBlocked = 'Yes' } - $Target = Test-TargetDN @PSBoundParameters + $testTargetDN = Test-TargetDN @PSBoundParameters $setGPInheritanceParams = @{ - Target = $Target + Target = $testTargetDN IsBlocked = $IsBlocked } if ($Domain) @@ -114,7 +114,7 @@ function Test-TargetResource ( [parameter(Mandatory = $true)] [string] - $Target, + $TargetDN, [string] $Domain, diff --git a/DSCResources/MSFT_GPInheritance/MSFT_GPInheritance.schema.mof b/DSCResources/MSFT_GPInheritance/MSFT_GPInheritance.schema.mof index 3e79c7f..1621d6e 100644 --- a/DSCResources/MSFT_GPInheritance/MSFT_GPInheritance.schema.mof +++ b/DSCResources/MSFT_GPInheritance/MSFT_GPInheritance.schema.mof @@ -1,8 +1,9 @@ [ClassVersion("1.0.0"), FriendlyName("GPInheritance")] class MSFT_GPInheritance : OMI_BaseResource { - [Key] String Target; - [write] String Domain; - [write] String Server; - [write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] string Ensure; + [Key, Description("Specifies the domain or the OU for which to block or unblock inheritance by its LDAP distinguished name.")] String TargetDN; + [Write, Description("Specifies the domain to run against.")] String Domain; + [Write, Description("Specifies the name of the domain controller that this resource contacts to complete the operation. +You can specify either the fully qualified domain name (FQDN) or the host name.")] String Server; + [Write, Description("Whether inheritance should be blocked (Absent) or unblocked (Present)."), ValueMap{"Present", "Absent"}, Values{"Present", "Absent"}] String Ensure; }; diff --git a/DSCResources/MSFT_GPOImport/MSFT_GPOImport.psm1 b/DSCResources/MSFT_GPOImport/MSFT_GPOImport.psm1 index f0f8003..b27f15f 100644 --- a/DSCResources/MSFT_GPOImport/MSFT_GPOImport.psm1 +++ b/DSCResources/MSFT_GPOImport/MSFT_GPOImport.psm1 @@ -5,7 +5,7 @@ ( [parameter(Mandatory = $true)] [string] - $TargetName, + $Name, [parameter(Mandatory = $true)] [string] @@ -35,7 +35,7 @@ Import-Module -Name GroupPolicy -Verbose:$false $getGPOParams = @{ - Name = $TargetName + Name = $Name ErrorAction = 'SilentlyContinue' } if ($Domain) @@ -53,7 +53,7 @@ Write-Verbose -Message 'Getting GPO' $gpo = Get-GPO @getGPOParams $targetResource = @{ - TargetName = $TargetName + Name = $Name Path = $Path BackupIdentity = $BackupIdentity BackupIdentityType = $BackupIdentityType @@ -84,7 +84,7 @@ function Set-TargetResource ( [parameter(Mandatory = $true)] [string] - $TargetName, + $Name, [parameter(Mandatory = $true)] [string] @@ -114,7 +114,7 @@ function Set-TargetResource Import-Module -Name GroupPolicy -Verbose:$false $importGPOParams = @{ - TargetName = $TargetName + TargetName = $Name Path = $Path CreateIfNeeded = $true } @@ -159,7 +159,7 @@ function Test-TargetResource ( [parameter(Mandatory = $true)] [string] - $TargetName, + $Name, [parameter(Mandatory = $true)] [string] diff --git a/DSCResources/MSFT_GPOImport/MSFT_GPOImport.schema.mof b/DSCResources/MSFT_GPOImport/MSFT_GPOImport.schema.mof index 713bb7d..674ebc9 100644 --- a/DSCResources/MSFT_GPOImport/MSFT_GPOImport.schema.mof +++ b/DSCResources/MSFT_GPOImport/MSFT_GPOImport.schema.mof @@ -1,12 +1,13 @@ [ClassVersion("1.0.0"), FriendlyName("GPOImport")] class MSFT_GPOImport : OMI_BaseResource { - [Key] String TargetName; - [required] String Path; - [required] String BackupIdentity; - [write,ValueMap{"Name", "Guid"},Values{"Name", "Guid"}] string BackupIdentityType; - [write] String Domain; - [write] String MigrationTable; - [write] String Server; - [write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] string Ensure; + [Key, Description("Specifies the display name of the GPO into which the settings are to be imported.")] String Name; + [Required, Description("Specifies the path to the backup directory.")] String Path; + [Required, Description("Specifies the display name or backup ID of the backed-up GPO from which to import the settings.")] String BackupIdentity; + [Write, Description("Specifies the type of the BackupIdentity."), ValueMap{"Name", "Guid"}, Values{"Name", "Guid"}] String BackupIdentityType; + [Write, Description("Specifies the domain to run against.")] String Domain; + [Write, Description("Specifies the path to a migration table file. You can use a migration table to map security principals and UNC paths across domains.")] String MigrationTable; + [Write, Description("Specifies the name of the domain controller that this resource contacts to complete the operation. +You can specify either the fully qualified domain name (FQDN) or the host name.")] String Server; + [Write, Description("Must be Present.") ,ValueMap{"Present"}, Values{"Present"}] String Ensure; }; diff --git a/DSCResources/MSFT_GPOLink/MSFT_GPOLink.psm1 b/DSCResources/MSFT_GPOLink/MSFT_GPOLink.psm1 index 8f987dd..c26b0c6 100644 --- a/DSCResources/MSFT_GPOLink/MSFT_GPOLink.psm1 +++ b/DSCResources/MSFT_GPOLink/MSFT_GPOLink.psm1 @@ -4,15 +4,11 @@ ( [parameter(Mandatory = $true)] [string] - $Identity, - - [ValidateSet('Name','Guid')] - [string] - $IdentityType = 'Name', + $Name, [parameter(Mandatory = $true)] [string] - $Target, + $TargetDN, [string] $Domain, @@ -38,9 +34,9 @@ Import-Module $PSScriptRoot\..\Helper.psm1 -Verbose:$false Import-Module -Name GroupPolicy -Verbose:$false - $target = Test-TargetDN @PSBoundParameters + $testTargetDN = Test-TargetDN @PSBoundParameters $gpInheritanceparams = @{ - Target = $target + Target = $testTargetDN } if ($Server) { @@ -58,9 +54,8 @@ $gpoLinks = (Get-GPInheritance @gpInheritanceparams).GpoLinks $gpo = Get-GpoInfo @PSBoundParameters $targetResource = @{ - Identity = $Identity - IdentityType = $IdentityType - Target = $Target + Name = $Name + TargetDN = $testTargetDN Domain = $null Enforced = $null LinkEnabled = $null @@ -107,15 +102,11 @@ function Set-TargetResource { ( [parameter(Mandatory = $true)] [string] - $Identity, - - [ValidateSet('Name','Guid')] - [string] - $IdentityType = 'Name', + $Name, [parameter(Mandatory = $true)] [string] - $Target, + $TargetDN, [string] $Domain, @@ -147,24 +138,13 @@ function Set-TargetResource { if ($targetResource.Ensure -eq 'Present') { $setGPLinkParams = @{ - Target = $targetResource.Target - } - if ($IdentityType -eq 'Name') - { + Target = $targetResource.TargetDN <# Using the GpoId attribute of the GPO Links instead of the Name attribute because the Name attribute may take a while to replicate to all DCs if the GPO was recently created. #> - $setGPLinkParams += @{ - Guid = $gpo.Id - } - } - else - { - $setGPLinkParams += @{ - Guid = $Identity - } + Guid = $gpo.Id } if ($Domain) { @@ -202,24 +182,13 @@ function Set-TargetResource { else { $newGPLinkParams = @{ - Target = $targetResource.Target - } - if ($IdentityType -eq 'Name') - { + Target = $targetResource.TargetDN <# Using the GpoId attribute of the GPO Links instead of the Name attribute because the Name attribute may take a while to replicate to all DCs if the GPO was recently created. #> - $newGPLinkParams += @{ - Guid = $gpo.Id - } - } - else - { - $newGPLinkParams += @{ - Guid = $Identity - } + Guid = $gpo.Id } if ($Domain) { @@ -258,24 +227,13 @@ function Set-TargetResource { else { $removeGPLinkParams = @{ - Target = $targetResource.Target - } - if ($IdentityType -eq 'Name') - { + Target = $targetResource.TargetDN <# Using the GpoId attribute of the GPO Links instead of the Name attribute because the Name attribute may take a while to replicate to all DCs if the GPO was recently created. #> - $removeGPLinkParams += @{ - Guid = $gpo.Id - } - } - else - { - $removeGPLinkParams += @{ - Guid = $Identity - } + Guid = $gpo.Id } if ($Domain) { @@ -300,15 +258,11 @@ function Test-TargetResource { ( [parameter(Mandatory = $true)] [string] - $Identity, - - [ValidateSet('Name','Guid')] - [string] - $IdentityType = 'Name', + $Name, [parameter(Mandatory = $true)] [string] - $Target, + $TargetDN, [string] $Domain, @@ -368,24 +322,39 @@ function Get-GpoInfo param ( [parameter(Mandatory = $true)] - [string]$Identity, - [ValidateSet('Name','Guid')] - [string]$IdentityType = 'Name', + [string] + $Name, + [parameter(Mandatory = $true)] - [string]$Target, - [string]$Domain, + [string] + $TargetDN, + + [string] + $Domain, + [ValidateSet('Yes','No')] - [string]$Enforced, + [string] + $Enforced, + [ValidateSet('Yes','No')] - [string]$LinkEnabled, - [int16]$Order, - [string]$Server, + [string] + $LinkEnabled, + + [int16] + $Order, + + [string] + $Server, + [ValidateSet('Present','Absent')] - [string]$Ensure = 'Present' + [string] + $Ensure = 'Present' ) Import-Module -Name GroupPolicy -Verbose:$false - $getGPOParams = @{} + $getGPOParams = @{ + Name = $Name + } if ($Server) { $getGPOParams += @{ @@ -398,18 +367,6 @@ function Get-GpoInfo Domain = $Domain } } - if ($IdentityType -eq 'Name') - { - $getGPOParams += @{ - Name = $Identity - } - } - else - { - $getGPOParams += @{ - Guid = $Identity - } - } Write-Verbose -Message 'Getting GPO' Get-GPO @getGPOParams } diff --git a/DSCResources/MSFT_GPOLink/MSFT_GPOLink.schema.mof b/DSCResources/MSFT_GPOLink/MSFT_GPOLink.schema.mof index f0f81ba..c445469 100644 --- a/DSCResources/MSFT_GPOLink/MSFT_GPOLink.schema.mof +++ b/DSCResources/MSFT_GPOLink/MSFT_GPOLink.schema.mof @@ -1,13 +1,15 @@ [ClassVersion("1.0.0"), FriendlyName("GPOLink")] class MSFT_GPOLink : OMI_BaseResource { - [Key] String Identity; - [Write,ValueMap{"Name", "Guid"},Values{"Name", "Guid"}] String IdentityType; - [Key] String Target; - [Write] String Domain; - [Write,ValueMap{"Yes", "No"},Values{"Yes", "No"}] String Enforced; - [Write,ValueMap{"Yes", "No"},Values{"Yes", "No"}] String LinkEnabled; - [Write] Sint16 Order; - [Write] String Server; - [Write,ValueMap{"Present", "Absent"},Values{"Present", "Absent"}] String Ensure; + [Key, Description("Specifies the name of the GPO to link.")] String Name; + [Key, Description("Specifies the LDAP distinguished name of the site, domain, or OU to which to link the GPO. +You can also leave off the domain part of the distinguished name and it will be generated automatically.")] String TargetDN; + [Write, Description("Specifies the domain to run against.")] String Domain; + [Write, Description("Specifies whether the GPO link is enforced."), ValueMap{"Yes", "No"}, Values{"Yes", "No"}] String Enforced; + [Write, Description("Specifies whether the GPO link is enabled."), ValueMap{"Yes", "No"}, Values{"Yes", "No"}] String LinkEnabled; + [Write, Description("Specifies the link order for the GPO link. +You can specify a number that is between one and the current number of GPO links to the target site, domain, or OU, plus one.")] Sint16 Order; + [Write, Description("Specifies the name of the domain controller that this resource contacts to complete the operation. +You can specify either the fully qualified domain name (FQDN) or the host name.")] String Server; + [Write, Description("Whether the GPO Link should exist (Present) or not (Absent)."), ValueMap{"Present", "Absent"}, Values{"Present", "Absent"}] String Ensure; }; diff --git a/README.md b/README.md index 84b1685..f321767 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ It won't import settings into an existing GPO. ### GPInheritance -* **Target**: Specifies the domain or the OU for which to block or unblock inheritance by its LDAP distinguished name. +* **TargetDN**: Specifies the domain or the OU for which to block or unblock inheritance by its LDAP distinguished name. You can also leave off the domain part of the distinguished name and it will be generated automatically. See the UnblockInheritance.ps1 example in the Examples folder. * **Domain**: Specifies the domain to run against. @@ -32,7 +32,7 @@ Defaults to Present. ### GPOImport -* **TargetName**: Specifies the display name of the GPO into which the settings are to be imported. +* **Name**: Specifies the display name of the GPO into which the settings are to be imported. * **Path**: Specifies the path to the backup directory. * **BackupIdentity**: Specifies the display name or backup ID of the backed-up GPO from which to import the settings. * **BackupIdentityType**: Specifies the type of the BackupIdentity (Name or Guid). @@ -40,6 +40,7 @@ Defaults to Name. * **Domain**: Specifies the domain to run against. Optional. * **MigrationTable**: Specifies the path to a migration table file. +You can use a migration table to map security principals and UNC paths across domains. * **Server**: Specifies the name of the domain controller that this resource contacts to complete the operation. You can specify either the fully qualified domain name (FQDN) or the host name. Optional. @@ -48,10 +49,8 @@ Defaults to Present. ### GPOLink -* **Identity**: Specifies the GPO to link by its display name or GUID. -* **IdentityType**: Specifies the type of the Identity (Name or Guid). -Defaults to Name. -* **Target**: Specifies the LDAP distinguished name of the site, domain, or OU to which to link the GPO. +* **Name**: Specifies the name of the GPO to link. +* **TargetDN**: Specifies the LDAP distinguished name of the site, domain, or OU to which to link the GPO. You can also leave off the domain part of the distinguished name and it will be generated automatically. See the GpoLinkByGuidAndDisable.ps1 example in the Examples folder. * **Domain**: Specifies the domain to run against. From 70c9d746aaaf7e654a1f97900bf0e967c5788881 Mon Sep 17 00:00:00 2001 From: Cory Wood Date: Thu, 25 Aug 2016 14:38:40 -0500 Subject: [PATCH 11/13] Updated Helper.psm1 to reflect changes to parameter names. --- DSCResources/Helper.psm1 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/DSCResources/Helper.psm1 b/DSCResources/Helper.psm1 index ff5d728..5410f73 100644 --- a/DSCResources/Helper.psm1 +++ b/DSCResources/Helper.psm1 @@ -21,7 +21,7 @@ function Test-TargetDN ( [parameter(Mandatory = $true)] [string] - $Target, + $TargetDN, [string] $Domain, @@ -44,21 +44,21 @@ function Test-TargetDN Write-Verbose -Message ("Checking the Domain Distinguished Name is " + "present on the Target Distinguished Name.") $domainDN = (Get-ADDomain @getADDomainParams).DistinguishedName - if ($Target -like "*$domainDN") + if ($TargetDN -like "*$domainDN") { Write-Verbose -Message "Target has full DN." } else { Write-Verbose -Message "Adding the Domain Distinguished Name to the Target DN." - if ($Target.EndsWith(",")) + if ($TargetDN.EndsWith(",")) { - $Target = "$Target$domainDN" + $TargetDN = "$Target$domainDN" } else { - $Target = "$Target,$domainDN" + $TargetDN = "$Target,$domainDN" } } - Write-Output -InputObject $Target + Write-Output -InputObject $TargetDN } From 7d744dee694a102740164f407adbcf5cf9a511dd Mon Sep 17 00:00:00 2001 From: Cory Wood Date: Thu, 25 Aug 2016 14:59:56 -0500 Subject: [PATCH 12/13] Added $Name parameter to Helper.psm1 --- DSCResources/Helper.psm1 | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/DSCResources/Helper.psm1 b/DSCResources/Helper.psm1 index 5410f73..f7e8cc8 100644 --- a/DSCResources/Helper.psm1 +++ b/DSCResources/Helper.psm1 @@ -2,6 +2,9 @@ .SYNOPSIS Tests the $Target parameter to ensure it contains the RootDSE and adds it if it doesn't. + .PARAMETER Name + Not used. Included to allow @PSBoundParameters in function call. + .PARAMETER Target The target OU Distinguished Name with or without the RootDSE. @@ -19,6 +22,9 @@ function Test-TargetDN { param ( + [string] + $Name, + [parameter(Mandatory = $true)] [string] $TargetDN, @@ -53,11 +59,11 @@ function Test-TargetDN Write-Verbose -Message "Adding the Domain Distinguished Name to the Target DN." if ($TargetDN.EndsWith(",")) { - $TargetDN = "$Target$domainDN" + $TargetDN = "$TargetDN$domainDN" } else { - $TargetDN = "$Target,$domainDN" + $TargetDN = "$TargetDN,$domainDN" } } Write-Output -InputObject $TargetDN From 936621382b192a30727eb3edfe12099ebb0d8056 Mon Sep 17 00:00:00 2001 From: Cory Wood Date: Thu, 25 Aug 2016 15:19:58 -0500 Subject: [PATCH 13/13] Updated tests with new parameter names. --- .../MSFT_GPInheritance.Integration.tests.ps1 | 2 +- .../Integration/MSFT_GPInheritance.config.ps1 | 4 ++-- .../MSFT_GPOImport.Integration.tests.ps1 | 2 +- Tests/Integration/MSFT_GPOImport.config.ps1 | 4 ++-- .../MSFT_GPOLink.Integration.tests.ps1 | 5 ++-- Tests/Integration/MSFT_GPOLink.config.ps1 | 10 ++++---- Tests/Unit/MSFT_GPInheritance.Tests.ps1 | 24 ++----------------- Tests/Unit/MSFT_GPOImport.Tests.ps1 | 2 +- Tests/Unit/MSFT_GPOLink.Tests.ps1 | 5 ++-- 9 files changed, 17 insertions(+), 41 deletions(-) diff --git a/Tests/Integration/MSFT_GPInheritance.Integration.tests.ps1 b/Tests/Integration/MSFT_GPInheritance.Integration.tests.ps1 index 18a3574..d921c1c 100644 --- a/Tests/Integration/MSFT_GPInheritance.Integration.tests.ps1 +++ b/Tests/Integration/MSFT_GPInheritance.Integration.tests.ps1 @@ -43,7 +43,7 @@ try It 'Should have set the resource and all the parameters should match' { $current = Get-DscConfiguration - $current.Target | Should Be $GPInheritance.Target + $current.TargetDN | Should Be $GPInheritance.TargetDN $current.Server | Should Be $GPInheritance.Server $current.Ensure | Should Be $GPInheritance.Ensure } diff --git a/Tests/Integration/MSFT_GPInheritance.config.ps1 b/Tests/Integration/MSFT_GPInheritance.config.ps1 index 843e2de..a75e366 100644 --- a/Tests/Integration/MSFT_GPInheritance.config.ps1 +++ b/Tests/Integration/MSFT_GPInheritance.config.ps1 @@ -1,6 +1,6 @@ $ou = 'OU=Test OU,DC=testdomain,DC=local' $GPInheritance = @{ - Target = $ou + TargetDN = $ou Server = 'localhost' Ensure = 'Present' } @@ -8,7 +8,7 @@ configuration 'MSFT_GPInheritance_config' { Import-DscResource -Name 'MSFT_GPInheritance' node localhost { GPInheritance Integration_Test { - Target = $GPInheritance.Target + TargetDN = $GPInheritance.TargetDN Server = $GPInheritance.Server Ensure = $GPInheritance.Ensure } diff --git a/Tests/Integration/MSFT_GPOImport.Integration.tests.ps1 b/Tests/Integration/MSFT_GPOImport.Integration.tests.ps1 index f87dca8..29a33a3 100644 --- a/Tests/Integration/MSFT_GPOImport.Integration.tests.ps1 +++ b/Tests/Integration/MSFT_GPOImport.Integration.tests.ps1 @@ -43,7 +43,7 @@ try It 'Should have set the resource and all the parameters should match' { $current = Get-DscConfiguration - $current.TargetName | Should Be $GPO.TargetName + $current.Name | Should Be $GPO.Name $current.Path | Should Be $GPO.Path $current.BackupIdentity | Should Be $GPO.BackupIdentity $current.BackupIdentityType | Should Be $GPO.BackupIdentityType diff --git a/Tests/Integration/MSFT_GPOImport.config.ps1 b/Tests/Integration/MSFT_GPOImport.config.ps1 index d511313..f40e31a 100644 --- a/Tests/Integration/MSFT_GPOImport.config.ps1 +++ b/Tests/Integration/MSFT_GPOImport.config.ps1 @@ -1,7 +1,7 @@ $gpoName = 'Test GPO' $domainName = 'testdomain.local' $GPO = @{ - TargetName = $gpoName + Name = $gpoName Path = "C:\Test Path\GPO Backups\$gpoName" BackupIdentity = $gpoName BackupIdentityType = 'Name' @@ -13,7 +13,7 @@ configuration 'MSFT_GPOImport_config' { Import-DscResource -Name 'MSFT_GPOImport' node localhost { GPOImport Integration_Test { - TargetName = $GPO.TargetName + Name = $GPO.Name Path = $GPO.Path BackupIdentity = $GPO.BackupIdentity BackupIdentityType = $GPO.BackupIdentityType diff --git a/Tests/Integration/MSFT_GPOLink.Integration.tests.ps1 b/Tests/Integration/MSFT_GPOLink.Integration.tests.ps1 index 1567471..ccb0f01 100644 --- a/Tests/Integration/MSFT_GPOLink.Integration.tests.ps1 +++ b/Tests/Integration/MSFT_GPOLink.Integration.tests.ps1 @@ -43,9 +43,8 @@ try It 'Should have set the resource and all the parameters should match' { $current = Get-DscConfiguration - $current.Identity | Should Be $GPOLink.Identity - $current.IdentityType | Should Be $GPOLink.IdentityType - $current.Target | Should Be $GPOLink.Target + $current.Name | Should Be $GPOLink.Name + $current.TargetDN | Should Be $GPOLink.TargetDN $current.Enforced | Should Be $GPOLink.Enforced $current.LinkEnabled | Should Be $GPOLink.LinkEnabled $current.Order | Should Be $GPOLink.Order diff --git a/Tests/Integration/MSFT_GPOLink.config.ps1 b/Tests/Integration/MSFT_GPOLink.config.ps1 index a931a61..ad4f2e7 100644 --- a/Tests/Integration/MSFT_GPOLink.config.ps1 +++ b/Tests/Integration/MSFT_GPOLink.config.ps1 @@ -1,7 +1,6 @@ $GPOLink = @{ - Identity = 'Test GPO' - IdentityType = 'Name' - Target = 'OU=Test OU,DC=testdomain,DC=local' + Name = 'Test GPO' + TargetDN = 'OU=Test OU,DC=testdomain,DC=local' Enforced = 'No' LinkEnabled = 'Yes' Order = 1 @@ -11,9 +10,8 @@ configuration 'MSFT_GPOLink_config' { Import-DscResource -Name 'MSFT_GPOLink' node localhost { GPOLink Integration_Test { - Identity = $GPOLink.Identity - IdentityType = $GPOLink.IdentityType - Target = $GPOLink.Target + Name = $GPOLink.Identity + TargetDN = $GPOLink.TargetDN Enforced = $GPOLink.Enforced LinkEnabled = $GPOLink.LinkEnabled Order = $GPOLink.Order diff --git a/Tests/Unit/MSFT_GPInheritance.Tests.ps1 b/Tests/Unit/MSFT_GPInheritance.Tests.ps1 index 41eaf58..eb65679 100644 --- a/Tests/Unit/MSFT_GPInheritance.Tests.ps1 +++ b/Tests/Unit/MSFT_GPInheritance.Tests.ps1 @@ -36,17 +36,12 @@ try $rootDSE = 'DC=testdomain,DC=local' $ou = 'OU=Test OU' $presentParams = @{ - Target = "$ou,$rootDSE" - Server = 'localhost' - Ensure = 'Present' - } - $presentPartialOUParams = @{ - Target = "$ou," + TargetDN = "$ou,$rootDSE" Server = 'localhost' Ensure = 'Present' } $absentParams = @{ - Target = "$ou,$rootDSE" + TargetDN = "$ou,$rootDSE" Server = 'localhost' Ensure = 'Absent' } @@ -143,21 +138,6 @@ try } } #endregion - - - #region Function Test-TargetDN - Describe "$($Global:DSCResourceName)\Test-TargetDN" { - It "Returns $ou,$rootDSE when given partial OU DN" { - Mock -CommandName Get-ADDomain -MockWith {$fakeADDomain} - Test-TargetDN @presentPartialOUParams | Should Be "$ou,$rootDSE" - } - - It "Returns $ou,$rootDSE when given full OU DN" { - Mock -CommandName Get-ADDomain -MockWith {$fakeADDomain} - Test-TargetDN @presentParams | Should Be "$ou,$rootDSE" - } - } - #endregion } #endregion } diff --git a/Tests/Unit/MSFT_GPOImport.Tests.ps1 b/Tests/Unit/MSFT_GPOImport.Tests.ps1 index 19c5656..727f5b6 100644 --- a/Tests/Unit/MSFT_GPOImport.Tests.ps1 +++ b/Tests/Unit/MSFT_GPOImport.Tests.ps1 @@ -35,7 +35,7 @@ try $gpoName = 'Test GPO' $domainName = 'testdomain.local' $testParams = @{ - TargetName = $gpoName + Name = $gpoName Path = "C:\Test Path\GPO Backups\$gpoName" BackupIdentity = $gpoName BackupIdentityType = 'Name' diff --git a/Tests/Unit/MSFT_GPOLink.Tests.ps1 b/Tests/Unit/MSFT_GPOLink.Tests.ps1 index 99a1e70..449682d 100644 --- a/Tests/Unit/MSFT_GPOLink.Tests.ps1 +++ b/Tests/Unit/MSFT_GPOLink.Tests.ps1 @@ -42,9 +42,8 @@ try $ou = 'OU=Test OU' $domainName = 'testdomain.local' $presentParams = @{ - Identity = $gpoName - IdentityType = 'Name' - Target = "$ou,$rootDSE" + Name = $gpoName + TargetDN = "$ou,$rootDSE" Domain = $domainName Enforced = 'No' LinkEnabled = 'Yes'