diff --git a/CHANGELOG.md b/CHANGELOG.md index ad17ae15..032a99a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,9 @@ For older change log history see the [historic changelog](HISTORIC_CHANGELOG.md) - FailoverClusterDsc - URLs in module manifest now points to the renamed repository. + - Now you can use distinguished naming of cluster to place it in an + organizational unit of your choice, e.g parameter `Name` can be se to + `'CN=CLUSTER,OU=BUSINESS,DC=RANDOM,DC=LOCAL'`. ## [2.1.0] - 2022-06-19 diff --git a/build.yaml b/build.yaml index 5a615bb8..3f24112f 100644 --- a/build.yaml +++ b/build.yaml @@ -6,6 +6,7 @@ CopyPaths: - en-US - DSCResources + - Modules Encoding: UTF8 VersionedOutputDirectory: true diff --git a/source/DSCResources/DSC_Cluster/DSC_Cluster.psm1 b/source/DSCResources/DSC_Cluster/DSC_Cluster.psm1 index a0c9a83d..8c13b2a0 100644 --- a/source/DSCResources/DSC_Cluster/DSC_Cluster.psm1 +++ b/source/DSCResources/DSC_Cluster/DSC_Cluster.psm1 @@ -1,6 +1,8 @@ $script:resourceHelperModulePath = Join-Path -Path $PSScriptRoot -ChildPath '..\..\Modules\DscResource.Common' +$script:failoverClusterHelperModulePath = Join-Path -Path $PSScriptRoot -ChildPath '..\..\Modules\FailoverClusterDsc.Common' Import-Module -Name $script:resourceHelperModulePath +Import-Module -Name $script:failoverClusterHelperModulePath $script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US' @@ -72,7 +74,7 @@ function Get-TargetResource ($oldToken, $context, $newToken) = Set-ImpersonateAs -Credential $DomainAdministratorCredential } - $cluster = Get-Cluster -Name $Name -Domain $computerInformation.Domain + $cluster = Get-Cluster -Name (Convert-DistinguishedNameToSimpleName -DistinguishedName $Name) -Domain $computerInformation.Domain if ($null -eq $cluster) { $errorMessage = $script:localizedData.ClusterNameNotFound -f $Name @@ -80,7 +82,7 @@ function Get-TargetResource } # This will return the IP address regardless if using Static IP or DHCP. - $address = Get-ClusterResource -Cluster $Name -Name 'Cluster IP Address' | Get-ClusterParameter -Name 'Address' + $address = Get-ClusterResource -Cluster (Convert-DistinguishedNameToSimpleName -DistinguishedName $Name) -Name 'Cluster IP Address' | Get-ClusterParameter -Name 'Address' } finally { @@ -93,7 +95,7 @@ function Get-TargetResource } @{ - Name = $Name + Name = (Convert-DistinguishedNameToSimpleName -DistinguishedName $Name) StaticIPAddress = $address.Value IgnoreNetwork = $IgnoreNetwork DomainAdministratorCredential = $DomainAdministratorCredential @@ -174,7 +176,7 @@ function Set-TargetResource try { - $cluster = Get-Cluster -Name $Name -Domain $computerInformation.Domain + $cluster = Get-Cluster -Name (Convert-DistinguishedNameToSimpleName -DistinguishedName $Name) -Domain $computerInformation.Domain if ($cluster) { @@ -240,7 +242,7 @@ function Set-TargetResource Write-Verbose -Message ($script:localizedData.AddNodeToCluster -f $targetNodeName, $Name) - $list = Get-ClusterNode -Cluster $Name + $list = Get-ClusterNode -Cluster (Convert-DistinguishedNameToSimpleName -DistinguishedName $Name) foreach ($node in $list) { if ($node.Name -eq $targetNodeName) @@ -255,14 +257,13 @@ function Set-TargetResource { Write-Verbose -Message ($script:localizedData.RemoveOfflineNodeFromCluster -f $targetNodeName, $Name) - Remove-ClusterNode -Name $targetNodeName -Cluster $Name -Force + Remove-ClusterNode -Name $targetNodeName -Cluster (Convert-DistinguishedNameToSimpleName -DistinguishedName $Name) -Force } } } } - - Add-ClusterNode -Name $targetNodeName -Cluster $Name -NoStorage + Add-ClusterNode -Name $targetNodeName -Cluster (Convert-DistinguishedNameToSimpleName -DistinguishedName $Name) -NoStorage Write-Verbose -Message ($script:localizedData.AddNodeToClusterSuccessful -f $targetNodeName, $Name) } @@ -366,7 +367,7 @@ function Test-TargetResource ($oldToken, $context, $newToken) = Set-ImpersonateAs -Credential $DomainAdministratorCredential } - $cluster = Get-Cluster -Name $Name -Domain $ComputerInfo.Domain + $cluster = Get-Cluster -Name (Convert-DistinguishedNameToSimpleName -DistinguishedName $Name) -Domain $ComputerInfo.Domain Write-Verbose -Message ($script:localizedData.ClusterPresent -f $Name) @@ -376,7 +377,7 @@ function Test-TargetResource Write-Verbose -Message ($script:localizedData.CheckClusterNodeIsUp -f $targetNodeName, $Name) - $allNodes = Get-ClusterNode -Cluster $Name + $allNodes = Get-ClusterNode -Cluster (Convert-DistinguishedNameToSimpleName -DistinguishedName $Name) foreach ($node in $allNodes) { @@ -532,3 +533,5 @@ function Close-UserToken New-InvalidOperationException -Message $errorMessage } } + +Export-ModuleMember -Function *-TargetResource diff --git a/source/DSCResources/DSC_ClusterPreferredOwner/DSC_ClusterPreferredOwner.psm1 b/source/DSCResources/DSC_ClusterPreferredOwner/DSC_ClusterPreferredOwner.psm1 index f8c2f64d..647d436e 100644 --- a/source/DSCResources/DSC_ClusterPreferredOwner/DSC_ClusterPreferredOwner.psm1 +++ b/source/DSCResources/DSC_ClusterPreferredOwner/DSC_ClusterPreferredOwner.psm1 @@ -1,6 +1,8 @@ $script:resourceHelperModulePath = Join-Path -Path $PSScriptRoot -ChildPath '..\..\Modules\DscResource.Common' +$script:failoverClusterHelperModulePath = Join-Path -Path $PSScriptRoot -ChildPath '..\..\Modules\FailoverClusterDsc.Common' Import-Module -Name $script:resourceHelperModulePath +Import-Module -Name $script:failoverClusterHelperModulePath $script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US' @@ -56,7 +58,7 @@ function Get-TargetResource $ownerNodes = @( Write-Verbose -Message ($script:localizedData.GetOwnerInformationForClusterGroup -f $ClusterGroup) - ((Get-ClusterGroup -Cluster $ClusterName | Where-Object -FilterScript { + ((Get-ClusterGroup -Cluster (Convert-DistinguishedNameToSimpleName -DistinguishedName $ClusterName) | Where-Object -FilterScript { $_.Name -like $ClusterGroup } | Get-ClusterOwnerNode).OwnerNodes).Name @@ -65,7 +67,7 @@ function Get-TargetResource foreach ($resource in $ClusterResources) { Write-Verbose -Message ($script:localizedData.GetOwnerInformationForClusterResource -f $resource) - ((Get-ClusterResource -Cluster $ClusterName | Where-Object -FilterScript { + ((Get-ClusterResource -Cluster (Convert-DistinguishedNameToSimpleName -DistinguishedName $ClusterName) | Where-Object -FilterScript { $_.Name -like $resource } | Get-ClusterOwnerNode).OwnerNodes).Name } @@ -76,7 +78,7 @@ function Get-TargetResource @{ ClusterGroup = $ClusterGroup - ClusterName = $ClusterName + ClusterName = (Convert-DistinguishedNameToSimpleName -DistinguishedName $ClusterName) Nodes = $ownerNodes ClusterResources = $ClusterResources Ensure = $Ensure @@ -131,12 +133,12 @@ function Set-TargetResource ) Write-Verbose -Message ($script:localizedData.GetAllNodesOfCluster -f $ClusterName) - $allNodes = (Get-ClusterNode -Cluster $ClusterName).Name + $allNodes = (Get-ClusterNode -Cluster (Convert-DistinguishedNameToSimpleName -DistinguishedName $ClusterName)).Name if ($Ensure -eq 'Present') { Write-Verbose -Message ($script:localizedData.SetOwnerForClusterGroup -f $ClusterGroup, $Nodes) - $null = Get-ClusterGroup -Cluster $ClusterName | Where-Object -FilterScript { + $null = Get-ClusterGroup -Cluster (Convert-DistinguishedNameToSimpleName -DistinguishedName $ClusterName) | Where-Object -FilterScript { $_.Name -like $ClusterGroup } | Set-ClusterOwnerNode -Owners $Nodes @@ -145,14 +147,14 @@ function Set-TargetResource } | Set-ClusterOwnerNode -Owners $allNodes Write-Verbose -Message ($script:localizedData.MoveClusterGroup -f $ClusterGroup, $Nodes[0]) - $null = Get-ClusterGroup -Cluster $ClusterName | Where-Object -FilterScript { + $null = Get-ClusterGroup -Cluster (Convert-DistinguishedNameToSimpleName -DistinguishedName $ClusterName) | Where-Object -FilterScript { $_.name -like $ClusterGroup } | Move-ClusterGroup -Node $Nodes[0] foreach ($resource in $ClusterResources) { Write-Verbose -Message ($script:localizedData.SetOwnerForClusterResource -f $resource, $Nodes) - $null = Get-ClusterResource -Cluster $ClusterName | Where-Object -FilterScript { + $null = Get-ClusterResource -Cluster (Convert-DistinguishedNameToSimpleName -DistinguishedName $ClusterName) | Where-Object -FilterScript { $_.Name -like $resource } | Set-ClusterOwnerNode -Owners $Nodes } @@ -161,7 +163,7 @@ function Set-TargetResource if ($Ensure -eq 'Absent') { Write-Verbose -Message ($script:localizedData.GetOwnerInformationForClusterGroup -f $ClusterGroup) - $currentOwners = ((Get-ClusterGroup -Cluster $ClusterName | Where-Object -FilterScript { + $currentOwners = ((Get-ClusterGroup -Cluster (Convert-DistinguishedNameToSimpleName -DistinguishedName $ClusterName) | Where-Object -FilterScript { $_.Name -like $ClusterGroup } | Get-ClusterOwnerNode).OwnerNodes).Name | Sort-Object -Unique @@ -176,7 +178,7 @@ function Set-TargetResource ) Write-Verbose -Message ($script:localizedData.RemoveOwnerFromClusterGroup -f $ClusterGroup, $Nodes) - $null = Get-ClusterGroup -Cluster $ClusterName | Where-Object -FilterScript { + $null = Get-ClusterGroup -Cluster (Convert-DistinguishedNameToSimpleName -DistinguishedName $ClusterName) | Where-Object -FilterScript { $_.Name -like $ClusterGroup } | Set-ClusterOwnerNode $newOwners @@ -186,14 +188,14 @@ function Set-TargetResource } | Set-ClusterOwnerNode $allNodes Write-Verbose -Message ($script:localizedData.MoveClusterGroup -f $ClusterGroup, $newOwners[0]) - $null = Get-ClusterGroup -Cluster $ClusterName | Where-Object -FilterScript { + $null = Get-ClusterGroup -Cluster (Convert-DistinguishedNameToSimpleName -DistinguishedName $ClusterName) | Where-Object -FilterScript { $_.Name -like $ClusterGroup } | Move-ClusterGroup -Node $newOwners[0] foreach ($resource in $ClusterResources) { Write-Verbose -Message ($script:localizedData.GetOwnerInformationForClusterResource -f $resource) - $currentOwners = ((Get-ClusterResource -Cluster $ClusterName | Where-Object -FilterScript { + $currentOwners = ((Get-ClusterResource -Cluster (Convert-DistinguishedNameToSimpleName -DistinguishedName $ClusterName) | Where-Object -FilterScript { $_.Name -like $resource } | Get-ClusterOwnerNode).OwnerNodes).Name | Sort-Object -Unique @@ -208,7 +210,7 @@ function Set-TargetResource ) Write-Verbose -Message ($script:localizedData.SetOwnerForClusterResource -f $resource, $newOwners) - $null = Get-ClusterResource -Cluster $ClusterName | Where-Object -FilterScript { + $null = Get-ClusterResource -Cluster (Convert-DistinguishedNameToSimpleName -DistinguishedName $ClusterName) | Where-Object -FilterScript { $_.Name -like $resource } | Set-ClusterOwnerNode -Owners $newOwners } @@ -313,3 +315,5 @@ function Test-TargetResource $result } + +Export-ModuleMember -Function *-TargetResource diff --git a/source/DSCResources/DSC_ClusterProperty/DSC_ClusterProperty.psm1 b/source/DSCResources/DSC_ClusterProperty/DSC_ClusterProperty.psm1 index 87050547..5f0bebd0 100644 --- a/source/DSCResources/DSC_ClusterProperty/DSC_ClusterProperty.psm1 +++ b/source/DSCResources/DSC_ClusterProperty/DSC_ClusterProperty.psm1 @@ -1,6 +1,8 @@ $script:resourceHelperModulePath = Join-Path -Path $PSScriptRoot -ChildPath '..\..\Modules\DscResource.Common' +$script:failoverClusterHelperModulePath = Join-Path -Path $PSScriptRoot -ChildPath '..\..\Modules\FailoverClusterDsc.Common' Import-Module -Name $script:resourceHelperModulePath +Import-Module -Name $script:failoverClusterHelperModulePath $script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US' @@ -24,9 +26,9 @@ function Get-TargetResource Write-Verbose -Message ($script:localizedData.GettingClusterProperties -f $Name) - $cluster = Get-Cluster -Name $Name + $cluster = Get-Cluster -Name (Convert-DistinguishedNameToSimpleName -DistinguishedName $Name) $returnValue = @{ - Name = $Name + Name = (Convert-DistinguishedNameToSimpleName -DistinguishedName $Name) AddEvictDelay = $cluster.AddEvictDelay BlockCacheSize = $cluster.BlockCacheSize ClusterLogLevel = $cluster.ClusterLogLevel @@ -214,7 +216,7 @@ function Set-TargetResource $boundParameters.Remove('Name') | Out-Null $boundParameters.Remove('Verbose') | Out-Null - $cluster = Get-Cluster -Name $Name + $cluster = Get-Cluster -Name (Convert-DistinguishedNameToSimpleName -DistinguishedName $Name) foreach ($boundParameter in $boundParameters.GetEnumerator()) { Write-Verbose -Message ($script:localizedData.SettingClusterProperty -f $($boundParameter.Key), $boundParameter.Value) @@ -387,7 +389,7 @@ function Test-TargetResource $boundParameters.Remove('Verbose') | Out-Null $boundParameters.Remove('Debug') | Out-Null - $cluster = Get-Cluster -Name $Name + $cluster = Get-Cluster -Name (Convert-DistinguishedNameToSimpleName -DistinguishedName $Name) $output = $true @@ -405,3 +407,4 @@ function Test-TargetResource } Export-ModuleMember -Function *-TargetResource +Export-ModuleMember -Function *-TargetResource diff --git a/source/DSCResources/DSC_WaitForCluster/DSC_WaitForCluster.psm1 b/source/DSCResources/DSC_WaitForCluster/DSC_WaitForCluster.psm1 index f1b99ae9..7c6fe36b 100644 --- a/source/DSCResources/DSC_WaitForCluster/DSC_WaitForCluster.psm1 +++ b/source/DSCResources/DSC_WaitForCluster/DSC_WaitForCluster.psm1 @@ -1,6 +1,8 @@ $script:resourceHelperModulePath = Join-Path -Path $PSScriptRoot -ChildPath '..\..\Modules\DscResource.Common' +$script:failoverClusterHelperModulePath = Join-Path -Path $PSScriptRoot -ChildPath '..\..\Modules\FailoverClusterDsc.Common' Import-Module -Name $script:resourceHelperModulePath +Import-Module -Name $script:failoverClusterHelperModulePath $script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US' @@ -40,7 +42,7 @@ function Get-TargetResource Write-Verbose -Message $script:localizedData.ReturnParameterValues @{ - Name = $Name + Name = (Convert-DistinguishedNameToSimpleName -DistinguishedName $Name) RetryIntervalSec = $RetryIntervalSec RetryCount = $RetryCount } @@ -92,7 +94,7 @@ function Set-TargetResource break } - $cluster = Get-Cluster -Name $Name -Domain $computerObject.Domain + $cluster = Get-Cluster -Name (Convert-DistinguishedNameToSimpleName -DistinguishedName $Name) -Domain $computerObject.Domain if ($null -ne $cluster) { @@ -162,7 +164,7 @@ function Test-TargetResource } else { - $cluster = Get-Cluster -Name $Name -Domain $computerObject.Domain + $cluster = Get-Cluster -Name (Convert-DistinguishedNameToSimpleName -DistinguishedName $Name) -Domain $computerObject.Domain if ($null -eq $cluster) { Write-Verbose -Message ($script:localizedData.ClusterAbsentWithDomain -f $Name, $computerObject.Domain) @@ -182,3 +184,4 @@ function Test-TargetResource $testTargetResourceReturnValue } +Export-ModuleMember -Function *-TargetResource diff --git a/source/Modules/FailoverClusterDsc.Common/FailoverClusterDsc.Common.psd1 b/source/Modules/FailoverClusterDsc.Common/FailoverClusterDsc.Common.psd1 new file mode 100644 index 00000000..518ac160 --- /dev/null +++ b/source/Modules/FailoverClusterDsc.Common/FailoverClusterDsc.Common.psd1 @@ -0,0 +1,42 @@ +@{ + # Script module or binary module file associated with this manifest. + RootModule = 'FailoverClusterDsc.Common.psm1' + + # Version number of this module. + ModuleVersion = '1.0.0' + + # ID used to uniquely identify this module + GUID = '7ef908fb-3e4b-4807-a8d5-9a6ca6daadb1' + + # Author of this module + Author = 'DSC Community' + + # Company or vendor of this module + CompanyName = 'DSC Community' + + # Copyright statement for this module + Copyright = 'Copyright the DSC Community contributors. All rights reserved.' + + # Description of the functionality provided by this module + Description = 'Functions used by the DSC resources in FailoverClusterDsc.' + + # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. + FunctionsToExport = @( + 'Convert-DistinguishedNameToSimpleName' + ) + + # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. + CmdletsToExport = @() + + # Variables to export from this module + VariablesToExport = @() + + # Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export. + AliasesToExport = @() + + # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. + PrivateData = @{ + PSData = @{ + } # End of PSData hashtable + } # End of PrivateData hashtable +} diff --git a/source/Modules/FailoverClusterDsc.Common/FailoverClusterDsc.Common.psm1 b/source/Modules/FailoverClusterDsc.Common/FailoverClusterDsc.Common.psm1 new file mode 100644 index 00000000..e324c6cf --- /dev/null +++ b/source/Modules/FailoverClusterDsc.Common/FailoverClusterDsc.Common.psm1 @@ -0,0 +1,34 @@ +$script:resourceHelperModulePath = Join-Path -Path $PSScriptRoot -ChildPath '..\..\Modules\DscResource.Common' + +Import-Module -Name $script:resourceHelperModulePath + +$script:localizedData = Get-LocalizedData -DefaultUICulture 'en-US' + +<# + .SYNOPSIS + This method is used to converted Distinguished Name to a Simple Name. + + .PARAMETER CurrentValues + Distinguished Name to be converted to a Simple Name +#> +function Convert-DistinguishedNameToSimpleName +{ + [Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', 'returnValue')] + [CmdletBinding()] + [OutputType([string])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $DistinguishedName + ) + + $returnValue = $DistinguishedName + + if ($DistinguishedName -match '^(\s*CN\s*=\w*)((\s*,\s*OU\s*=\w*)*)((\s*,\s*DC\s*=\w*)*)$') + { + $returnValue = ((($DistinguishedName -split ',')[0]) -split '=')[1] + } + + return $returnValue +} diff --git a/source/Modules/FailoverClusterDsc.Common/en-US/FailoverClusterDsc.Common.strings.psd1 b/source/Modules/FailoverClusterDsc.Common/en-US/FailoverClusterDsc.Common.strings.psd1 new file mode 100644 index 00000000..dfe27a24 --- /dev/null +++ b/source/Modules/FailoverClusterDsc.Common/en-US/FailoverClusterDsc.Common.strings.psd1 @@ -0,0 +1,3 @@ +# Localized resources for FailoverClusterDsc.Common +ConvertFrom-StringData @' +'@ diff --git a/tests/Unit/FailoverClusterDsc.Common.Tests.ps1 b/tests/Unit/FailoverClusterDsc.Common.Tests.ps1 new file mode 100644 index 00000000..ba3c935d --- /dev/null +++ b/tests/Unit/FailoverClusterDsc.Common.Tests.ps1 @@ -0,0 +1,25 @@ +$script:dscModuleName = 'FailoverClusterDsc' +$script:subModuleName = 'FailoverClusterDsc.Common' + +$script:parentModule = Get-Module -Name $script:dscModuleName -ListAvailable | Select-Object -First 1 +$script:subModulesFolder = Join-Path -Path $script:parentModule.ModuleBase -ChildPath 'Modules' + +$script:subModulePath = Join-Path -Path $script:subModulesFolder -ChildPath $script:subModuleName + +Import-Module -Name $script:subModulePath -Force -ErrorAction 'Stop' + +Describe 'FailoverClusterDsc.Common\Convert-DistinguishedNameToSimpleName' -Tag 'Convert-DistinguishedNameToSimpleName' { + Context 'When passing a distinguished name' { + It 'Should return the expected cluster name' { + Convert-DistinguishedNameToSimpleName -DistinguishedName 'CN=CLUSTER1,OU=BUSINESS,DC=RANDOM,DC=LOCAL' | + Should -Be 'CLUSTER1' + } + } + + Context 'When passing a cluster name' { + It 'Should return the expected cluster name' { + Convert-DistinguishedNameToSimpleName -DistinguishedName 'CLUSTER2' | + Should -Be 'CLUSTER2' + } + } +}