From 08c8fc0705b6c7cc789f0e55cfb4463afa27fc02 Mon Sep 17 00:00:00 2001 From: James Pogran Date: Fri, 9 Feb 2018 14:22:01 -0500 Subject: [PATCH 01/25] (maint) Fix including HQ DSC Resources in yml This commit fixes building both HQ DSC Resources as well as Experimental DSC Resources by fixing the method to update the dsc_resource_tags.yml and updating the dsc_resource_tags.yml with the current list of HQ DSC Resources. --- build/dsc.rake | 8 +++++--- dsc_resource_release_tags.yml | 5 +++++ 2 files changed, 10 insertions(+), 3 deletions(-) diff --git a/build/dsc.rake b/build/dsc.rake index 5b39ca12d..bebfd6a63 100644 --- a/build/dsc.rake +++ b/build/dsc.rake @@ -189,12 +189,14 @@ eod resource_tags["#{dsc_resource_name}"] = checkout_version.encode("UTF-8") end end - + resource_tags = resource_tags.reject do |r| blacklist.include?(r) end - - File.open("#{dsc_resources_file}", 'w+') { |f| f.write resource_tags.to_yaml } + + # We use YAML.dump here to update the file instead of overwriting it. This ensures + # we can write both HQ DSC Resources as well as Expertimental ones to the same yml + File.open("#{dsc_resources_file}", 'w+') { |f| YAML.dump(resource_tags, f) } end desc <<-eod diff --git a/dsc_resource_release_tags.yml b/dsc_resource_release_tags.yml index 43eda47c6..2ead5e545 100644 --- a/dsc_resource_release_tags.yml +++ b/dsc_resource_release_tags.yml @@ -1,4 +1,9 @@ --- +AuditPolicyDsc: 1.1.0.0-PSGallery +OfficeOnlineServerDsc: 1.0.0.0-PSGallery +SecurityPolicyDsc: 1.5.0.0-PSGallery +SharePointDsc: 1.8.0.0-PSGallery +SystemLocaleDsc: 1.1.0.0-PSGallery xActiveDirectory: 2.16.0.0-PSGallery xAdcsDeployment: 1.1.0.0-PSGallery xAzure: 0.2.0.0-PSGallery From 68dbbd73affd9000ad010ed3fb09ad715657359f Mon Sep 17 00:00:00 2001 From: James Pogran Date: Fri, 9 Feb 2018 14:24:23 -0500 Subject: [PATCH 02/25] (maint) Fix ignoring PSDscResources in yml In commit 44f2bd4 we added PSDscResources to the blacklist because it is a side-by-side release of the same DSC Resources that are built into DSC as well as some DSC Resources included in xPSDscResources, and we can't build all of those without overwritting all of them. This commit fixes this attempt by including PSDscResources in the filter that ignores certain DSC Resources when adding them to the dsc_resource_tags.yml file. --- build/dsc.rake | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build/dsc.rake b/build/dsc.rake index bebfd6a63..167a9f656 100644 --- a/build/dsc.rake +++ b/build/dsc.rake @@ -73,7 +73,7 @@ eod community_dsc_resources_root = "#{dsc_resources_path_tmp}/xDscResources" official_dsc_resources_root = "#{dsc_resources_path_tmp}/DscResources" composite_resources = [ 'xChrome','xDSCResourceDesigner','xDscDiagnostics', - 'xFirefox','xSafeHarbor','xSystemSecurity' ] + 'xFirefox','xSafeHarbor','xSystemSecurity', 'PSDscResources' ] Rake::Task['dsc:resources:checkout'].invoke( community_dsc_resources_root, update_versions, composite_resources) From cbe4467d2b42a0e83f763b89c6635f4fb006531d Mon Sep 17 00:00:00 2001 From: James Pogran Date: Fri, 9 Feb 2018 14:44:58 -0500 Subject: [PATCH 03/25] (maint) Remove warning for MSFT_WaitFor DSC Resources In commit a5147a6 we added a warning to remove any DSC Resources that match the name 'MSFT_WaitFor`. This did not prevent some DSC Resources that do perform a `WaitFor` type function from being included over time, and now presents a problem with updating official DSC Resources (the warning prevents us from including parts of updated DSC Resource modules). Since it would potentially cause unintended problems to pick and choose which parts of a DSC Resource were included in our build process, it was decided to remove the warning altogether and allow `WaitFor` DSC Resources to be included, and warn the user in the READEME that these DSC Resources may not work as expected. --- README.md | 2 ++ build/dsc.rake | 2 -- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 9c370afea..49348d45a 100644 --- a/README.md +++ b/README.md @@ -367,6 +367,8 @@ Where available, a link to the external GitHub repo of each resource is also inc ### Known Issues +- The `WaitFor*` type of DSC Resources may not work with this module. These DSC Resources use sleeps, timers, or locking to 'wait' for other resources to be in a specified state. These waits would 'pause' a Puppet run for an amount of time that varies between DSC Resource implementations, which may cause unintended problems in the Puppet run. Puppet cannot test all possible interactions from these `WaitFor*` DSC Resources, and does not support them at this time. + - The `dsc_log` resource might not appear to work. The ["Log" resource](https://technet.microsoft.com/en-us/library/Dn282117.aspx) writes events to the 'Microsoft-Windows-Desired State Configuration/Analytic' event log, which is [disabled by default](https://technet.microsoft.com/en-us/library/Cc749492.aspx). - You might have issues if you attempt to use `dsc_ensure => absent` with `dsc_service` with services that are not running. diff --git a/build/dsc.rake b/build/dsc.rake index 167a9f656..36a0500aa 100644 --- a/build/dsc.rake +++ b/build/dsc.rake @@ -224,8 +224,6 @@ eod task :build, [:module_path] do |t, args| module_path = args[:module_path] || default_dsc_module_path m = Dsc::Manager.new - wait_for_resources = Dir["#{module_path}/**/MSFT_WaitFor*"] - fail "MSFT_WaitFor* resources found - aborting type building! Please remove the following MSFT_WaitFor* DSC Resources and run the build again.\n\n#{wait_for_resources}\n" if !wait_for_resources.empty? m.target_module_path = module_path msgs = m.build_dsc_types msgs.each{|m| puts "#{m}"} From cf6e00e6b42a5624c7afc50f3b1748c3858aa368 Mon Sep 17 00:00:00 2001 From: James Pogran Date: Fri, 9 Feb 2018 14:55:40 -0500 Subject: [PATCH 04/25] (MODULES-6592) Update StorageDsc to 4.0.0.0 This commit updates StorageDsc to the latest gallery versions~ --- dsc_resource_release_tags.yml | 3 +- lib/puppet/type/{dsc_xdisk.rb => dsc_disk.rb} | 24 +- ...iskaccesspath.rb => dsc_diskaccesspath.rb} | 24 +- .../{dsc_xmountimage.rb => dsc_mountimage.rb} | 16 +- lib/puppet/type/dsc_opticaldiskdriveletter.rb | 120 ++++++ ...dsc_xwaitfordisk.rb => dsc_waitfordisk.rb} | 24 +- ...xwaitforvolume.rb => dsc_waitforvolume.rb} | 16 +- .../DSCResources/MSFT_Disk/MSFT_Disk.psm1} | 106 +++-- .../MSFT_Disk/MSFT_Disk.schema.mof} | 6 +- .../MSFT_Disk/en-us/MSFT_Disk.strings.psd1} | 3 + .../MSFT_DiskAccessPath.psm1} | 184 +++++---- .../MSFT_DiskAccessPath.schema.mof} | 6 +- .../en-us/MSFT_DiskAccessPath.strings.psd1} | 3 + .../MSFT_MountImage/MSFT_MountImage.psm1} | 2 +- .../MSFT_MountImage.schema.mof} | 4 +- .../en-us/MSFT_MountImage.strings.psd1} | 0 .../MSFT_OpticalDiskDriveLetter.psm1 | 373 ++++++++++++++++++ .../MSFT_OpticalDiskDriveLetter.schema.mof | 8 + .../MSFT_OpticalDiskDriveLetter.strings.psd1 | 15 + .../MSFT_WaitForDisk/MSFT_WaitForDisk.psm1} | 30 +- .../MSFT_WaitForDisk.schema.mof} | 6 +- .../en-us/MSFT_WaitForDisk.strings.psd1} | 0 .../MSFT_WaitForVolume.psm1} | 2 +- .../MSFT_WaitForVolume.schema.mof} | 4 +- .../en-us/MSFT_WaitForVolume.strings.psd1} | 0 .../{xStorage => StorageDsc}/LICENSE | 2 +- .../StorageDsc.Common/StorageDsc.Common.psm1 | 99 ++++- .../en-us/StorageDsc.Common.strings.psd1 | 0 .../StorageDsc.ResourceHelper.psm1 | 2 +- .../StorageDsc.psd1} | 35 +- types.md | 81 ++-- 31 files changed, 929 insertions(+), 269 deletions(-) rename lib/puppet/type/{dsc_xdisk.rb => dsc_disk.rb} (90%) rename lib/puppet/type/{dsc_xdiskaccesspath.rb => dsc_diskaccesspath.rb} (88%) rename lib/puppet/type/{dsc_xmountimage.rb => dsc_mountimage.rb} (91%) create mode 100644 lib/puppet/type/dsc_opticaldiskdriveletter.rb rename lib/puppet/type/{dsc_xwaitfordisk.rb => dsc_waitfordisk.rb} (84%) rename lib/puppet/type/{dsc_xwaitforvolume.rb => dsc_waitforvolume.rb} (87%) rename lib/puppet_x/dsc_resources/{xStorage/DSCResources/MSFT_xDisk/MSFT_xDisk.psm1 => StorageDsc/DSCResources/MSFT_Disk/MSFT_Disk.psm1} (89%) rename lib/puppet_x/dsc_resources/{xStorage/DSCResources/MSFT_xDisk/MSFT_xDisk.schema.mof => StorageDsc/DSCResources/MSFT_Disk/MSFT_Disk.schema.mof} (83%) rename lib/puppet_x/dsc_resources/{xStorage/DSCResources/MSFT_xDisk/en-us/MSFT_xDisk.strings.psd1 => StorageDsc/DSCResources/MSFT_Disk/en-us/MSFT_Disk.strings.psd1} (90%) rename lib/puppet_x/dsc_resources/{xStorage/DSCResources/MSFT_xDiskAccessPath/MSFT_xDiskAccessPath.psm1 => StorageDsc/DSCResources/MSFT_DiskAccessPath/MSFT_DiskAccessPath.psm1} (78%) rename lib/puppet_x/dsc_resources/{xStorage/DSCResources/MSFT_xDiskAccessPath/MSFT_xDiskAccessPath.schema.mof => StorageDsc/DSCResources/MSFT_DiskAccessPath/MSFT_DiskAccessPath.schema.mof} (75%) rename lib/puppet_x/dsc_resources/{xStorage/DSCResources/MSFT_xDiskAccessPath/en-us/MSFT_xDiskAccessPath.strings.psd1 => StorageDsc/DSCResources/MSFT_DiskAccessPath/en-us/MSFT_DiskAccessPath.strings.psd1} (89%) rename lib/puppet_x/dsc_resources/{xStorage/DSCResources/MSFT_xMountImage/MSFT_xMountImage.psm1 => StorageDsc/DSCResources/MSFT_MountImage/MSFT_MountImage.psm1} (99%) rename lib/puppet_x/dsc_resources/{xStorage/DSCResources/MSFT_xMountImage/MSFT_xMountImage.schema.mof => StorageDsc/DSCResources/MSFT_MountImage/MSFT_MountImage.schema.mof} (90%) rename lib/puppet_x/dsc_resources/{xStorage/DSCResources/MSFT_xMountImage/en-us/MSFT_xMountImage.strings.psd1 => StorageDsc/DSCResources/MSFT_MountImage/en-us/MSFT_MountImage.strings.psd1} (100%) create mode 100644 lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_OpticalDiskDriveLetter/MSFT_OpticalDiskDriveLetter.psm1 create mode 100644 lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_OpticalDiskDriveLetter/MSFT_OpticalDiskDriveLetter.schema.mof create mode 100644 lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_OpticalDiskDriveLetter/en-us/MSFT_OpticalDiskDriveLetter.strings.psd1 rename lib/puppet_x/dsc_resources/{xStorage/DSCResources/MSFT_xWaitForDisk/MSFT_xWaitForDisk.psm1 => StorageDsc/DSCResources/MSFT_WaitForDisk/MSFT_WaitForDisk.psm1} (92%) rename lib/puppet_x/dsc_resources/{xStorage/DSCResources/MSFT_xWaitForDisk/MSFT_xWaitForDisk.schema.mof => StorageDsc/DSCResources/MSFT_WaitForDisk/MSFT_WaitForDisk.schema.mof} (64%) rename lib/puppet_x/dsc_resources/{xStorage/DSCResources/MSFT_xWaitForDisk/en-us/MSFT_xWaitForDisk.strings.psd1 => StorageDsc/DSCResources/MSFT_WaitForDisk/en-us/MSFT_WaitForDisk.strings.psd1} (100%) rename lib/puppet_x/dsc_resources/{xStorage/DSCResources/MSFT_xWaitForVolume/MSFT_xWaitForVolume.psm1 => StorageDsc/DSCResources/MSFT_WaitForVolume/MSFT_WaitForVolume.psm1} (99%) rename lib/puppet_x/dsc_resources/{xStorage/DSCResources/MSFT_xWaitForVolume/MSFT_xWaitForVolume.schema.mof => StorageDsc/DSCResources/MSFT_WaitForVolume/MSFT_WaitForVolume.schema.mof} (77%) rename lib/puppet_x/dsc_resources/{xStorage/DSCResources/MSFT_xWaitForVolume/en-us/MSFT_xWaitForVolume.strings.psd1 => StorageDsc/DSCResources/MSFT_WaitForVolume/en-us/MSFT_WaitForVolume.strings.psd1} (100%) rename lib/puppet_x/dsc_resources/{xStorage => StorageDsc}/LICENSE (96%) rename lib/puppet_x/dsc_resources/{xStorage => StorageDsc}/Modules/StorageDsc.Common/StorageDsc.Common.psm1 (54%) rename lib/puppet_x/dsc_resources/{xStorage => StorageDsc}/Modules/StorageDsc.Common/en-us/StorageDsc.Common.strings.psd1 (100%) rename lib/puppet_x/dsc_resources/{xStorage => StorageDsc}/Modules/StorageDsc.ResourceHelper/StorageDsc.ResourceHelper.psm1 (99%) rename lib/puppet_x/dsc_resources/{xStorage/xStorage.psd1 => StorageDsc/StorageDsc.psd1} (75%) diff --git a/dsc_resource_release_tags.yml b/dsc_resource_release_tags.yml index 2ead5e545..5025cae83 100644 --- a/dsc_resource_release_tags.yml +++ b/dsc_resource_release_tags.yml @@ -3,6 +3,7 @@ AuditPolicyDsc: 1.1.0.0-PSGallery OfficeOnlineServerDsc: 1.0.0.0-PSGallery SecurityPolicyDsc: 1.5.0.0-PSGallery SharePointDsc: 1.8.0.0-PSGallery +StorageDsc: 4.0.0.0-PSGallery SystemLocaleDsc: 1.1.0.0-PSGallery xActiveDirectory: 2.16.0.0-PSGallery xAdcsDeployment: 1.1.0.0-PSGallery @@ -41,7 +42,7 @@ xSCVMM: 1.2.4.0-PSGallery xSharePoint: 1.8.0.0-PSGallery xSmbShare: 2.0.0.0-PSGallery xSqlPs: 1.4.0.0-PSGallery -xSQLServer: 7.0.0.0-PSGallery # Keep at version 7.0.0 due to PUP-7888 (long file names) +xSQLServer: 7.0.0.0-PSGallery xStorage: 3.2.0.0-PSGallery xTimeZone: 1.6.0.0-PSGallery xWebAdministration: 1.18.0.0-PSGallery diff --git a/lib/puppet/type/dsc_xdisk.rb b/lib/puppet/type/dsc_disk.rb similarity index 90% rename from lib/puppet/type/dsc_xdisk.rb rename to lib/puppet/type/dsc_disk.rb index 2a578c47e..ba7efd14b 100644 --- a/lib/puppet/type/dsc_xdisk.rb +++ b/lib/puppet/type/dsc_disk.rb @@ -1,14 +1,14 @@ require 'pathname' -Puppet::Type.newtype(:dsc_xdisk) do +Puppet::Type.newtype(:dsc_disk) do require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' @doc = %q{ - The DSC xDisk resource type. + The DSC Disk resource type. Automatically generated from - 'xStorage/DSCResources/MSFT_xDisk/MSFT_xDisk.schema.mof' + 'StorageDsc/DSCResources/MSFT_Disk/MSFT_Disk.schema.mof' To learn more about PowerShell Desired State Configuration, please visit https://technet.microsoft.com/en-us/library/dn249912.aspx. @@ -24,10 +24,10 @@ fail('dsc_driveletter is a required attribute') if self[:dsc_driveletter].nil? end - def dscmeta_resource_friendly_name; 'xDisk' end - def dscmeta_resource_name; 'MSFT_xDisk' end - def dscmeta_module_name; 'xStorage' end - def dscmeta_module_version; '3.2.0.0' end + def dscmeta_resource_friendly_name; 'Disk' end + def dscmeta_resource_name; 'MSFT_Disk' end + def dscmeta_module_name; 'StorageDsc' end + def dscmeta_module_version; '4.0.0.0' end newparam(:name, :namevar => true ) do end @@ -88,17 +88,17 @@ def mof_is_embedded?; false end # Name: DiskIdType # Type: string # IsMandatory: False - # Values: ["Number", "UniqueId"] + # Values: ["Number", "UniqueId", "Guid"] newparam(:dsc_diskidtype) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "DiskIdType - Specifies the identifier type the DiskId contains. Defaults to Number. Valid values are Number, UniqueId." + desc "DiskIdType - Specifies the identifier type the DiskId contains. Defaults to Number. Valid values are Number, UniqueId, Guid." validate do |value| unless value.kind_of?(String) fail("Invalid value '#{value}'. Should be a string") end - unless ['Number', 'number', 'UniqueId', 'uniqueid'].include?(value) - fail("Invalid value '#{value}'. Valid values are Number, UniqueId") + unless ['Number', 'number', 'UniqueId', 'uniqueid', 'Guid', 'guid'].include?(value) + fail("Invalid value '#{value}'. Valid values are Number, UniqueId, Guid") end end end @@ -211,7 +211,7 @@ def builddepends end end -Puppet::Type.type(:dsc_xdisk).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do +Puppet::Type.type(:dsc_disk).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) defaultfor :operatingsystem => :windows diff --git a/lib/puppet/type/dsc_xdiskaccesspath.rb b/lib/puppet/type/dsc_diskaccesspath.rb similarity index 88% rename from lib/puppet/type/dsc_xdiskaccesspath.rb rename to lib/puppet/type/dsc_diskaccesspath.rb index b5df8236a..d5b43c9db 100644 --- a/lib/puppet/type/dsc_xdiskaccesspath.rb +++ b/lib/puppet/type/dsc_diskaccesspath.rb @@ -1,14 +1,14 @@ require 'pathname' -Puppet::Type.newtype(:dsc_xdiskaccesspath) do +Puppet::Type.newtype(:dsc_diskaccesspath) do require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' @doc = %q{ - The DSC xDiskAccessPath resource type. + The DSC DiskAccessPath resource type. Automatically generated from - 'xStorage/DSCResources/MSFT_xDiskAccessPath/MSFT_xDiskAccessPath.schema.mof' + 'StorageDsc/DSCResources/MSFT_DiskAccessPath/MSFT_DiskAccessPath.schema.mof' To learn more about PowerShell Desired State Configuration, please visit https://technet.microsoft.com/en-us/library/dn249912.aspx. @@ -24,10 +24,10 @@ fail('dsc_accesspath is a required attribute') if self[:dsc_accesspath].nil? end - def dscmeta_resource_friendly_name; 'xDiskAccessPath' end - def dscmeta_resource_name; 'MSFT_xDiskAccessPath' end - def dscmeta_module_name; 'xStorage' end - def dscmeta_module_version; '3.2.0.0' end + def dscmeta_resource_friendly_name; 'DiskAccessPath' end + def dscmeta_resource_name; 'MSFT_DiskAccessPath' end + def dscmeta_module_name; 'StorageDsc' end + def dscmeta_module_version; '4.0.0.0' end newparam(:name, :namevar => true ) do end @@ -88,17 +88,17 @@ def mof_is_embedded?; false end # Name: DiskIdType # Type: string # IsMandatory: False - # Values: ["Number", "UniqueId"] + # Values: ["Number", "UniqueId", "Guid"] newparam(:dsc_diskidtype) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "DiskIdType - Specifies the identifier type the DiskId contains. Defaults to Number. Valid values are Number, UniqueId." + desc "DiskIdType - Specifies the identifier type the DiskId contains. Defaults to Number. Valid values are Number, UniqueId, Guid." validate do |value| unless value.kind_of?(String) fail("Invalid value '#{value}'. Should be a string") end - unless ['Number', 'number', 'UniqueId', 'uniqueid'].include?(value) - fail("Invalid value '#{value}'. Valid values are Number, UniqueId") + unless ['Number', 'number', 'UniqueId', 'uniqueid', 'Guid', 'guid'].include?(value) + fail("Invalid value '#{value}'. Valid values are Number, UniqueId, Guid") end end end @@ -179,7 +179,7 @@ def builddepends end end -Puppet::Type.type(:dsc_xdiskaccesspath).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do +Puppet::Type.type(:dsc_diskaccesspath).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) defaultfor :operatingsystem => :windows diff --git a/lib/puppet/type/dsc_xmountimage.rb b/lib/puppet/type/dsc_mountimage.rb similarity index 91% rename from lib/puppet/type/dsc_xmountimage.rb rename to lib/puppet/type/dsc_mountimage.rb index 899480b84..631d5ffdc 100644 --- a/lib/puppet/type/dsc_xmountimage.rb +++ b/lib/puppet/type/dsc_mountimage.rb @@ -1,14 +1,14 @@ require 'pathname' -Puppet::Type.newtype(:dsc_xmountimage) do +Puppet::Type.newtype(:dsc_mountimage) do require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' @doc = %q{ - The DSC xMountImage resource type. + The DSC MountImage resource type. Automatically generated from - 'xStorage/DSCResources/MSFT_xMountImage/MSFT_xMountImage.schema.mof' + 'StorageDsc/DSCResources/MSFT_MountImage/MSFT_MountImage.schema.mof' To learn more about PowerShell Desired State Configuration, please visit https://technet.microsoft.com/en-us/library/dn249912.aspx. @@ -24,10 +24,10 @@ fail('dsc_imagepath is a required attribute') if self[:dsc_imagepath].nil? end - def dscmeta_resource_friendly_name; 'xMountImage' end - def dscmeta_resource_name; 'MSFT_xMountImage' end - def dscmeta_module_name; 'xStorage' end - def dscmeta_module_version; '3.2.0.0' end + def dscmeta_resource_friendly_name; 'MountImage' end + def dscmeta_resource_name; 'MSFT_MountImage' end + def dscmeta_module_name; 'StorageDsc' end + def dscmeta_module_version; '4.0.0.0' end newparam(:name, :namevar => true ) do end @@ -148,7 +148,7 @@ def builddepends end end -Puppet::Type.type(:dsc_xmountimage).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do +Puppet::Type.type(:dsc_mountimage).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) defaultfor :operatingsystem => :windows diff --git a/lib/puppet/type/dsc_opticaldiskdriveletter.rb b/lib/puppet/type/dsc_opticaldiskdriveletter.rb new file mode 100644 index 000000000..499499e9e --- /dev/null +++ b/lib/puppet/type/dsc_opticaldiskdriveletter.rb @@ -0,0 +1,120 @@ +require 'pathname' + +Puppet::Type.newtype(:dsc_opticaldiskdriveletter) do + require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' + require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' + + + @doc = %q{ + The DSC OpticalDiskDriveLetter resource type. + Automatically generated from + 'StorageDsc/DSCResources/MSFT_OpticalDiskDriveLetter/MSFT_OpticalDiskDriveLetter.schema.mof' + + To learn more about PowerShell Desired State Configuration, please + visit https://technet.microsoft.com/en-us/library/dn249912.aspx. + + For more information about built-in DSC Resources, please visit + https://technet.microsoft.com/en-us/library/dn249921.aspx. + + For more information about xDsc Resources, please visit + https://github.com/PowerShell/DscResources. + } + + validate do + fail('dsc_diskid is a required attribute') if self[:dsc_diskid].nil? + end + + def dscmeta_resource_friendly_name; 'OpticalDiskDriveLetter' end + def dscmeta_resource_name; 'MSFT_OpticalDiskDriveLetter' end + def dscmeta_module_name; 'StorageDsc' end + def dscmeta_module_version; '4.0.0.0' end + + newparam(:name, :namevar => true ) do + end + + ensurable do + newvalue(:exists?) { provider.exists? } + newvalue(:present) { provider.create } + newvalue(:absent) { provider.destroy } + defaultto { :present } + end + + # Name: PsDscRunAsCredential + # Type: MSFT_Credential + # IsMandatory: False + # Values: None + newparam(:dsc_psdscrunascredential) do + def mof_type; 'MSFT_Credential' end + def mof_is_embedded?; true end + desc "PsDscRunAsCredential" + validate do |value| + unless value.kind_of?(Hash) + fail("Invalid value '#{value}'. Should be a hash") + end + PuppetX::Dsc::TypeHelpers.validate_MSFT_Credential("Credential", value) + end + end + + # Name: DiskId + # Type: string + # IsMandatory: True + # Values: None + newparam(:dsc_diskid) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "DiskId - Specifies the optical disk number for the disk to assign the drive letter to." + isrequired + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: DriveLetter + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_driveletter) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "DriveLetter - Specifies the drive letter to assign to the optical disk. Can be a single letter, optionally followed by a colon. This value is ignored if Ensure is set to Absent." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Ensure + # Type: string + # IsMandatory: False + # Values: ["Present", "Absent"] + newparam(:dsc_ensure) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Ensure - Determines whether a drive letter should be assigned to the optical disk. Defaults to 'Present'. Valid values are Present, Absent." + validate do |value| + resource[:ensure] = value.downcase + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + unless ['Present', 'present', 'Absent', 'absent'].include?(value) + fail("Invalid value '#{value}'. Valid values are Present, Absent") + end + end + end + + + def builddepends + pending_relations = super() + PuppetX::Dsc::TypeHelpers.ensure_reboot_relationship(self, pending_relations) + end +end + +Puppet::Type.type(:dsc_opticaldiskdriveletter).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do + confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) + defaultfor :operatingsystem => :windows + + mk_resource_methods +end diff --git a/lib/puppet/type/dsc_xwaitfordisk.rb b/lib/puppet/type/dsc_waitfordisk.rb similarity index 84% rename from lib/puppet/type/dsc_xwaitfordisk.rb rename to lib/puppet/type/dsc_waitfordisk.rb index 28dbd4a16..adfe4b4b9 100644 --- a/lib/puppet/type/dsc_xwaitfordisk.rb +++ b/lib/puppet/type/dsc_waitfordisk.rb @@ -1,14 +1,14 @@ require 'pathname' -Puppet::Type.newtype(:dsc_xwaitfordisk) do +Puppet::Type.newtype(:dsc_waitfordisk) do require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' @doc = %q{ - The DSC xWaitForDisk resource type. + The DSC WaitForDisk resource type. Automatically generated from - 'xStorage/DSCResources/MSFT_xWaitForDisk/MSFT_xWaitForDisk.schema.mof' + 'StorageDsc/DSCResources/MSFT_WaitForDisk/MSFT_WaitForDisk.schema.mof' To learn more about PowerShell Desired State Configuration, please visit https://technet.microsoft.com/en-us/library/dn249912.aspx. @@ -24,10 +24,10 @@ fail('dsc_diskid is a required attribute') if self[:dsc_diskid].nil? end - def dscmeta_resource_friendly_name; 'xWaitForDisk' end - def dscmeta_resource_name; 'MSFT_xWaitForDisk' end - def dscmeta_module_name; 'xStorage' end - def dscmeta_module_version; '3.2.0.0' end + def dscmeta_resource_friendly_name; 'WaitForDisk' end + def dscmeta_resource_name; 'MSFT_WaitForDisk' end + def dscmeta_module_name; 'StorageDsc' end + def dscmeta_module_version; '4.0.0.0' end newparam(:name, :namevar => true ) do end @@ -73,17 +73,17 @@ def mof_is_embedded?; false end # Name: DiskIdType # Type: string # IsMandatory: False - # Values: ["Number", "UniqueId"] + # Values: ["Number", "UniqueId", "Guid"] newparam(:dsc_diskidtype) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "DiskIdType - Specifies the identifier type the DiskId contains. Defaults to Number. Valid values are Number, UniqueId." + desc "DiskIdType - Specifies the identifier type the DiskId contains. Defaults to Number. Valid values are Number, UniqueId, Guid." validate do |value| unless value.kind_of?(String) fail("Invalid value '#{value}'. Should be a string") end - unless ['Number', 'number', 'UniqueId', 'uniqueid'].include?(value) - fail("Invalid value '#{value}'. Valid values are Number, UniqueId") + unless ['Number', 'number', 'UniqueId', 'uniqueid', 'Guid', 'guid'].include?(value) + fail("Invalid value '#{value}'. Valid values are Number, UniqueId, Guid") end end end @@ -131,7 +131,7 @@ def builddepends end end -Puppet::Type.type(:dsc_xwaitfordisk).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do +Puppet::Type.type(:dsc_waitfordisk).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) defaultfor :operatingsystem => :windows diff --git a/lib/puppet/type/dsc_xwaitforvolume.rb b/lib/puppet/type/dsc_waitforvolume.rb similarity index 87% rename from lib/puppet/type/dsc_xwaitforvolume.rb rename to lib/puppet/type/dsc_waitforvolume.rb index 899fe6c07..67698434d 100644 --- a/lib/puppet/type/dsc_xwaitforvolume.rb +++ b/lib/puppet/type/dsc_waitforvolume.rb @@ -1,14 +1,14 @@ require 'pathname' -Puppet::Type.newtype(:dsc_xwaitforvolume) do +Puppet::Type.newtype(:dsc_waitforvolume) do require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' @doc = %q{ - The DSC xWaitForVolume resource type. + The DSC WaitForVolume resource type. Automatically generated from - 'xStorage/DSCResources/MSFT_xWaitForVolume/MSFT_xWaitForVolume.schema.mof' + 'StorageDsc/DSCResources/MSFT_WaitForVolume/MSFT_WaitForVolume.schema.mof' To learn more about PowerShell Desired State Configuration, please visit https://technet.microsoft.com/en-us/library/dn249912.aspx. @@ -24,10 +24,10 @@ fail('dsc_driveletter is a required attribute') if self[:dsc_driveletter].nil? end - def dscmeta_resource_friendly_name; 'xWaitForVolume' end - def dscmeta_resource_name; 'MSFT_xWaitForVolume' end - def dscmeta_module_name; 'xStorage' end - def dscmeta_module_version; '3.2.0.0' end + def dscmeta_resource_friendly_name; 'WaitForVolume' end + def dscmeta_resource_name; 'MSFT_WaitForVolume' end + def dscmeta_module_name; 'StorageDsc' end + def dscmeta_module_version; '4.0.0.0' end newparam(:name, :namevar => true ) do end @@ -113,7 +113,7 @@ def builddepends end end -Puppet::Type.type(:dsc_xwaitforvolume).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do +Puppet::Type.type(:dsc_waitforvolume).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) defaultfor :operatingsystem => :windows diff --git a/lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xDisk/MSFT_xDisk.psm1 b/lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_Disk/MSFT_Disk.psm1 similarity index 89% rename from lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xDisk/MSFT_xDisk.psm1 rename to lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_Disk/MSFT_Disk.psm1 index 4b78dccfa..f66c90066 100644 --- a/lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xDisk/MSFT_xDisk.psm1 +++ b/lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_Disk/MSFT_Disk.psm1 @@ -1,4 +1,4 @@ -# Suppressed as per PSSA Rule Severity guidelines for unit/integration tests: +# Suppressed as per PSSA Rule Severity guidelines for unit/integration tests: # https://github.com/PowerShell/DscResources/blob/master/PSSARuleSeverities.md [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')] param () @@ -17,7 +17,7 @@ Import-Module -Name (Join-Path -Path $modulePath ` # Import Localization Strings $localizedData = Get-LocalizedData ` - -ResourceName 'MSFT_xDisk' ` + -ResourceName 'MSFT_Disk' ` -ResourcePath (Split-Path -Parent $Script:MyInvocation.MyCommand.Path) <# @@ -66,7 +66,7 @@ function Get-TargetResource $DiskId, [Parameter()] - [ValidateSet('Number', 'UniqueId')] + [ValidateSet('Number', 'UniqueId', 'Guid')] [System.String] $DiskIdType = 'Number', @@ -104,13 +104,10 @@ function Get-TargetResource # Validate the DriveLetter parameter $DriveLetter = Assert-DriveLetterValid -DriveLetter $DriveLetter - $diskIdParameter = @{ - $DiskIdType = $DiskId - } - - $disk = Get-Disk ` - @diskIdParameter ` - -ErrorAction SilentlyContinue + # Get the Disk using the identifiers supplied + $disk = Get-DiskByIdentifier ` + -DiskId $DiskId ` + -DiskIdType $DiskIdType $partition = Get-Partition ` -DriveLetter $DriveLetter ` @@ -154,7 +151,7 @@ function Get-TargetResource Specifies the identifier type the DiskId contains. Defaults to Number. .PARAMETER Size - Specifies the size of new volume (use all available space on disk if not provided). + Specifies the size of new volume. Leave empty to use the remaining free space. .PARAMETER FSLabel Specifies the volume label to assign to the volume. @@ -187,7 +184,7 @@ function Set-TargetResource $DiskId, [Parameter()] - [ValidateSet('Number', 'UniqueId')] + [ValidateSet('Number', 'UniqueId', 'Guid')] [System.String] $DiskIdType = 'Number', @@ -225,13 +222,10 @@ function Set-TargetResource # Validate the DriveLetter parameter $DriveLetter = Assert-DriveLetterValid -DriveLetter $DriveLetter - $diskIdParameter = @{ - $DiskIdType = $DiskId - } - - $disk = Get-Disk ` - @diskIdParameter ` - -ErrorAction Stop + # Get the Disk using the identifiers supplied + $disk = Get-DiskByIdentifier ` + -DiskId $DiskId ` + -DiskIdType $DiskIdType if ($disk.IsOffline) { @@ -258,7 +252,7 @@ function Set-TargetResource Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($localizedData.CheckingDiskPartitionStyleMessage -f $DiskIdType, $DiskId) - ) -join '' ) + ) -join '' ) if ($AllowDestructive -and $ClearDisk -and $disk.PartitionStyle -ne 'RAW') { @@ -268,7 +262,11 @@ function Set-TargetResource ) -join '' ) $disk | Clear-Disk -RemoveData -RemoveOEM -Confirm:$true - $disk = $disk | Get-Disk + + # Requery the disk + $disk = Get-DiskByIdentifier ` + -DiskId $DiskId ` + -DiskIdType $DiskIdType } switch ($disk.PartitionStyle) @@ -331,7 +329,7 @@ function Set-TargetResource { # Find the first basic partition matching the size $partition = $partition | - Where-Object -Filter { $_.Type -eq 'Basic' -and $_.Size -eq $Size } | + Where-Object -FilterScript { $_.Type -eq 'Basic' -and $_.Size -eq $Size } | Select-Object -First 1 if ($partition) @@ -349,8 +347,45 @@ function Set-TargetResource } else { - # No size specified so no partition can be matched + <# + No size specified, so see if there is a partition that has a volume + matching the file system type that is not assigned to a drive letter. + #> + Write-Verbose -Message ($localizedData.MatchingPartitionNoSizeMessage -f ` + $DiskIdType, $DiskId) + + $searchPartitions = $partition | Where-Object -FilterScript { + $_.Type -eq 'Basic' -and -not [System.Char]::IsLetter($_.DriveLetter) + } + $partition = $null + + foreach ($searchPartition in $searchPartitions) + { + # Look for the volume in the partition. + Write-Verbose -Message ($localizedData.SearchForVolumeMessage -f ` + $DiskIdType, $DiskId, $searchPartition.PartitionNumber, $FSFormat) + + $searchVolumes = $searchPartition | Get-Volume + + $volumeMatch = $searchVolumes | Where-Object -FilterScript { + $_.FileSystem -eq $FSFormat + } + + if ($volumeMatch) + { + <# + Found a partition with a volume that matches file system + type and not assigned a drive letter. + #> + $partition = $searchPartition + + Write-Verbose -Message ($localizedData.VolumeFoundMessage -f ` + $DiskIdType, $DiskId, $searchPartition.PartitionNumber, $FSFormat) + + break + } # if + } # foreach } # if } # if @@ -440,7 +475,7 @@ function Set-TargetResource $($localizedData.ResizeRefsNotPossible ` -f $DriveLetter, $assignedPartition.Size, $Size) ) -join '' ) - + } else { @@ -448,10 +483,10 @@ function Set-TargetResource "$($MyInvocation.MyCommand): " $($localizedData.SizeMismatchCorrection ` -f $DriveLetter, $assignedPartition.Size, $Size) - ) -join '' ) - + ) -join '' ) + $supportedSize = ($assignedPartition | Get-PartitionSupportedSize) - + if ($size -gt $supportedSize.SizeMax) { New-InvalidArgumentException -Message ( @( @@ -565,7 +600,7 @@ function Set-TargetResource "$($MyInvocation.MyCommand): " $($localizedData.SuccessfullyInitializedMessage -f $DriveLetter) ) -join '' ) - } # if + } # if } # Set-TargetResource <# @@ -582,7 +617,7 @@ function Set-TargetResource Specifies the identifier type the DiskId contains. Defaults to Number. .PARAMETER Size - Specifies the size of new volume (use all available space on disk if not provided). + Specifies the size of new volume. Leave empty to use the remaining free space. .PARAMETER FSLabel Specifies the volume label to assign to the volume. @@ -614,7 +649,7 @@ function Test-TargetResource $DiskId, [Parameter()] - [ValidateSet('Number', 'UniqueId')] + [ValidateSet('Number', 'UniqueId', 'Guid')] [System.String] $DiskIdType = 'Number', @@ -652,18 +687,15 @@ function Test-TargetResource # Validate the DriveLetter parameter $DriveLetter = Assert-DriveLetterValid -DriveLetter $DriveLetter - $diskIdParameter = @{ - $DiskIdType = $DiskId - } - Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($localizedData.CheckDiskInitializedMessage -f $DiskIdType, $DiskId) ) -join '' ) - $disk = Get-Disk ` - @diskIdParameter ` - -ErrorAction SilentlyContinue + # Get the Disk using the identifiers supplied + $disk = Get-DiskByIdentifier ` + -DiskId $DiskId ` + -DiskIdType $DiskIdType if (-not $disk) { diff --git a/lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xDisk/MSFT_xDisk.schema.mof b/lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_Disk/MSFT_Disk.schema.mof similarity index 83% rename from lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xDisk/MSFT_xDisk.schema.mof rename to lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_Disk/MSFT_Disk.schema.mof index c4839eedf..0b0c77aa2 100644 --- a/lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xDisk/MSFT_xDisk.schema.mof +++ b/lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_Disk/MSFT_Disk.schema.mof @@ -1,10 +1,10 @@ -[ClassVersion("1.0.0.0"), FriendlyName("xDisk")] -class MSFT_xDisk : OMI_BaseResource +[ClassVersion("1.0.0.0"), FriendlyName("Disk")] +class MSFT_Disk : OMI_BaseResource { [Key, Description("Specifies the identifier for which disk to modify.")] String DriveLetter; [Required, Description("Specifies the disk identifier for the disk to modify.")] String DiskId; - [Write, Description("Specifies the identifier type the DiskId contains. Defaults to Number."), ValueMap{"Number","UniqueId"}, Values{"Number","UniqueId"}] String DiskIdType; + [Write, Description("Specifies the identifier type the DiskId contains. Defaults to Number."), ValueMap{"Number","UniqueId","Guid"}, Values{"Number","UniqueId","Guid"}] String DiskIdType; [Write, Description("Specifies the size of new volume. Leave empty to use the remaining free space.")] Uint64 Size; [Write, Description("Define volume label if required.")] String FSLabel; [Write, Description("Specifies the allocation unit size to use when formatting the volume.")] Uint32 AllocationUnitSize; diff --git a/lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xDisk/en-us/MSFT_xDisk.strings.psd1 b/lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_Disk/en-us/MSFT_Disk.strings.psd1 similarity index 90% rename from lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xDisk/en-us/MSFT_xDisk.strings.psd1 rename to lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_Disk/en-us/MSFT_Disk.strings.psd1 index 28dfaa966..781ae6eac 100644 --- a/lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xDisk/en-us/MSFT_xDisk.strings.psd1 +++ b/lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_Disk/en-us/MSFT_Disk.strings.psd1 @@ -26,6 +26,9 @@ DriveLabelMismatch = Volume assigned to drive {0} label '{1}' does not match expected label '{2}'. PartitionAlreadyAssignedMessage = Partition '{1}' is already assigned as drive {0}. MatchingPartitionNotFoundMessage = Disk with {0} '{1}' already contains partitions, but none match required size. + MatchingPartitionNoSizeMessage = Disk with {0} '{1}' already contains partitions, but size parameter is not specified. + SearchForVolumeMessage = Searching for {3} volume with no drive letter on partition '{2}' disk with {0} '{1}'. + VolumeFoundMessage = Found {3} volume with no drive letter on partition '{2}' disk with {0} '{1}'. MatchingPartitionFoundMessage = Disk with {0} '{1}' already contains partitions, and partition '{2}' matches required size. DriveNotFoundOnPartitionMessage = Disk with {0} '{1}' does not contain a partition assigned to drive letter '{2}'. ClearingDisk = Clearing disk with {0} '{1}' of all existing partitions and volumes. diff --git a/lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xDiskAccessPath/MSFT_xDiskAccessPath.psm1 b/lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_DiskAccessPath/MSFT_DiskAccessPath.psm1 similarity index 78% rename from lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xDiskAccessPath/MSFT_xDiskAccessPath.psm1 rename to lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_DiskAccessPath/MSFT_DiskAccessPath.psm1 index a67e9f443..724dd417b 100644 --- a/lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xDiskAccessPath/MSFT_xDiskAccessPath.psm1 +++ b/lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_DiskAccessPath/MSFT_DiskAccessPath.psm1 @@ -1,4 +1,4 @@ -# Suppressed as per PSSA Rule Severity guidelines for unit/integration tests: +# Suppressed as per PSSA Rule Severity guidelines for unit/integration tests: # https://github.com/PowerShell/DscResources/blob/master/PSSARuleSeverities.md [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')] param () @@ -7,17 +7,17 @@ $modulePath = Join-Path -Path (Split-Path -Path (Split-Path -Path $PSScriptRoot # Import the Storage Common Modules Import-Module -Name (Join-Path -Path $modulePath ` - -ChildPath (Join-Path -Path 'StorageDsc.Common' ` - -ChildPath 'StorageDsc.Common.psm1')) + -ChildPath (Join-Path -Path 'StorageDsc.Common' ` + -ChildPath 'StorageDsc.Common.psm1')) # Import the Storage Resource Helper Module Import-Module -Name (Join-Path -Path $modulePath ` - -ChildPath (Join-Path -Path 'StorageDsc.ResourceHelper' ` - -ChildPath 'StorageDsc.ResourceHelper.psm1')) + -ChildPath (Join-Path -Path 'StorageDsc.ResourceHelper' ` + -ChildPath 'StorageDsc.ResourceHelper.psm1')) # Import Localization Strings $localizedData = Get-LocalizedData ` - -ResourceName 'MSFT_xDiskAccessPath' ` + -ResourceName 'MSFT_DiskAccessPath' ` -ResourcePath (Split-Path -Parent $Script:MyInvocation.MyCommand.Path) <# @@ -60,7 +60,7 @@ function Get-TargetResource $DiskId, [Parameter()] - [ValidateSet('Number','UniqueId')] + [ValidateSet('Number', 'UniqueId', 'Guid')] [System.String] $DiskIdType = 'Number', @@ -77,33 +77,30 @@ function Get-TargetResource $AllocationUnitSize, [Parameter()] - [ValidateSet('NTFS','ReFS')] + [ValidateSet('NTFS', 'ReFS')] [System.String] $FSFormat = 'NTFS' ) Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " - $($localizedData.GettingDiskMessage -f $DiskIdType,$DiskId,$AccessPath) + $($localizedData.GettingDiskMessage -f $DiskIdType, $DiskId, $AccessPath) ) -join '' ) # Validate the AccessPath parameter adding a trailing slash $AccessPath = Assert-AccessPathValid -AccessPath $AccessPath -Slash - $diskIdParameter = @{ - $DiskIdType = $DiskId - } - - $disk = Get-Disk ` - @diskIdParameter ` - -ErrorAction SilentlyContinue + # Get the Disk using the identifiers supplied + $disk = Get-DiskByIdentifier ` + -DiskId $DiskId ` + -DiskIdType $DiskIdType # Get the partitions on the disk $partition = $disk | Get-Partition -ErrorAction SilentlyContinue # Check if the disk has an existing partition assigned to the access path $assignedPartition = $partition | - Where-Object -Property AccessPaths -Contains -Value $AccessPath + Where-Object -Property AccessPaths -Contains -Value $AccessPath $volume = $assignedPartition | Get-Volume @@ -111,20 +108,20 @@ function Get-TargetResource $FSLabel = $volume.FileSystemLabel # Prepare the AccessPath used in the CIM query (replaces '\' with '\\') - $queryAccessPath = $AccessPath -replace '\\','\\' + $queryAccessPath = $AccessPath -replace '\\', '\\' $blockSize = (Get-CimInstance ` - -Query "SELECT BlockSize from Win32_Volume WHERE Name = '$queryAccessPath'" ` - -ErrorAction SilentlyContinue).BlockSize + -Query "SELECT BlockSize from Win32_Volume WHERE Name = '$queryAccessPath'" ` + -ErrorAction SilentlyContinue).BlockSize $returnValue = @{ - DiskId = $DiskId - DiskIdType = $DiskIdType - AccessPath = $AccessPath - Size = $assignedPartition.Size - FSLabel = $FSLabel + DiskId = $DiskId + DiskIdType = $DiskIdType + AccessPath = $AccessPath + Size = $assignedPartition.Size + FSLabel = $FSLabel AllocationUnitSize = $blockSize - FSFormat = $fileSystem + FSFormat = $fileSystem } $returnValue } # Get-TargetResource @@ -170,7 +167,7 @@ function Set-TargetResource $DiskId, [Parameter()] - [ValidateSet('Number','UniqueId')] + [ValidateSet('Number', 'UniqueId', 'Guid')] [System.String] $DiskIdType = 'Number', @@ -187,33 +184,30 @@ function Set-TargetResource $AllocationUnitSize, [Parameter()] - [ValidateSet('NTFS','ReFS')] + [ValidateSet('NTFS', 'ReFS')] [System.String] $FSFormat = 'NTFS' ) Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " - $($localizedData.SettingDiskMessage -f $DiskIdType,$DiskId,$AccessPath) + $($localizedData.SettingDiskMessage -f $DiskIdType, $DiskId, $AccessPath) ) -join '' ) # Validate the AccessPath parameter adding a trailing slash $AccessPath = Assert-AccessPathValid -AccessPath $AccessPath -Slash - $diskIdParameter = @{ - $DiskIdType = $DiskId - } - - $disk = Get-Disk ` - @diskIdParameter ` - -ErrorAction Stop + # Get the Disk using the identifiers supplied + $disk = Get-DiskByIdentifier ` + -DiskId $DiskId ` + -DiskIdType $DiskIdType if ($disk.IsOffline) { # Disk is offline, so bring it online Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " - $($localizedData.SetDiskOnlineMessage -f $DiskIdType,$DiskId) + $($localizedData.SetDiskOnlineMessage -f $DiskIdType, $DiskId) ) -join '' ) $disk | Set-Disk -IsOffline $false @@ -224,7 +218,7 @@ function Set-TargetResource # Disk is read-only, so make it read/write Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " - $($localizedData.SetDiskReadWriteMessage -f $DiskIdType,$DiskId) + $($localizedData.SetDiskReadWriteMessage -f $DiskIdType, $DiskId) ) -join '' ) $disk | Set-Disk -IsReadOnly $false @@ -232,7 +226,7 @@ function Set-TargetResource Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " - $($localizedData.CheckingDiskPartitionStyleMessage -f $DiskIdType,$DiskId) + $($localizedData.CheckingDiskPartitionStyleMessage -f $DiskIdType, $DiskId) ) -join '' ) switch ($disk.PartitionStyle) @@ -242,7 +236,7 @@ function Set-TargetResource # The disk partition table is not yet initialized, so initialize it with GPT Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " - $($localizedData.InitializingDiskMessage -f $DiskIdType,$DiskId) + $($localizedData.InitializingDiskMessage -f $DiskIdType, $DiskId) ) -join '' ) $disk | Initialize-Disk ` @@ -255,7 +249,7 @@ function Set-TargetResource # The disk partition is already initialized with GPT. Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " - $($localizedData.DiskAlreadyInitializedMessage -f $DiskIdType,$DiskId) + $($localizedData.DiskAlreadyInitializedMessage -f $DiskIdType, $DiskId) ) -join '' ) break } # 'GPT' @@ -265,7 +259,7 @@ function Set-TargetResource # This disk is initialized but not as GPT - so raise an exception. New-InvalidOperationException ` -Message ($localizedData.DiskAlreadyInitializedError -f ` - $DiskIdType,$DiskId,$Disk.PartitionStyle) + $DiskIdType, $DiskId, $Disk.PartitionStyle) } # default } # switch @@ -274,14 +268,14 @@ function Set-TargetResource # Check if the disk has an existing partition assigned to the access path $assignedPartition = $partition | - Where-Object -Property AccessPaths -Contains -Value $AccessPath + Where-Object -Property AccessPaths -Contains -Value $AccessPath if ($null -eq $assignedPartition) { # There is no partiton with this access path Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " - $($localizedData.AccessPathNotFoundOnPartitionMessage -f $DiskIdType,$DiskId,$AccessPath) + $($localizedData.AccessPathNotFoundOnPartitionMessage -f $DiskIdType, $DiskId, $AccessPath) ) -join '' ) # Are there any partitions defined on this disk? @@ -299,19 +293,56 @@ function Set-TargetResource { # A partition matching the required size was found Write-Verbose -Message ($localizedData.MatchingPartitionFoundMessage -f ` - $DiskIdType,$DiskId,$partition.PartitionNumber) + $DiskIdType, $DiskId, $partition.PartitionNumber) } else { # A partition matching the required size was not found Write-Verbose -Message ($localizedData.MatchingPartitionNotFoundMessage -f ` - $DiskIdType,$DiskId) + $DiskIdType, $DiskId) } # if } else { - # No size specified so no partition can be matched + <# + No size specified, so see if there is a partition that has a volume + matching the file system type that is not assigned to an access path. + #> + Write-Verbose -Message ($localizedData.MatchingPartitionNoSizeMessage -f ` + $DiskIdType, $DiskId) + + $searchPartitions = $partition | Where-Object -FilterScript { + $_.Type -eq 'Basic' -and -not (Test-AccessPathAssignedToLocal -AccessPath $_.AccessPaths) + } + $partition = $null + + foreach ($searchPartition in $searchPartitions) + { + # Look for the volume in the partition. + Write-Verbose -Message ($localizedData.SearchForVolumeMessage -f ` + $DiskIdType, $DiskId, $searchPartition.PartitionNumber, $FSFormat) + + $searchVolumes = $searchPartition | Get-Volume + + $volumeMatch = $searchVolumes | Where-Object -FilterScript { + $_.FileSystem -eq $FSFormat + } + + if ($volumeMatch) + { + <# + Found a partition with a volume that matches file system + type and not assigned an access path. + #> + $partition = $searchPartition + + Write-Verbose -Message ($localizedData.VolumeFoundMessage -f ` + $DiskIdType, $DiskId, $searchPartition.PartitionNumber, $FSFormat) + + break + } # if + } # foreach } # if } # if @@ -327,7 +358,7 @@ function Set-TargetResource Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($localizedData.CreatingPartitionMessage ` - -f $DiskIdType,$DiskId,"$($Size/1KB) KB") + -f $DiskIdType, $DiskId, "$($Size/1KB) KB") ) -join '' ) $partitionParams['Size'] = $Size } @@ -337,7 +368,7 @@ function Set-TargetResource Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($localizedData.CreatingPartitionMessage ` - -f $DiskIdType,$DiskId,'all free space') + -f $DiskIdType, $DiskId, 'all free space') ) -join '' ) $partitionParams['UseMaximumSize'] = $true } # if @@ -353,7 +384,7 @@ function Set-TargetResource while ($partition.IsReadOnly -and (Get-Date) -lt $timeout) { Write-Verbose -Message ($localizedData.NewPartitionIsReadOnlyMessage -f ` - $DiskIdType,$DiskId,$partition.PartitionNumber) + $DiskIdType, $DiskId, $partition.PartitionNumber) Start-Sleep -Seconds 1 @@ -367,7 +398,7 @@ function Set-TargetResource # The partition is still readonly - throw an exception New-InvalidOperationException ` -Message ($localizedData.NewParitionIsReadOnlyError -f ` - $DiskIdType,$DiskId,$partition.PartitionNumber) + $DiskIdType, $DiskId, $partition.PartitionNumber) } # if $assignAccessPath = $true @@ -378,7 +409,7 @@ function Set-TargetResource Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($localizedData.PartitionAlreadyAssignedMessage -f ` - $AccessPath,$partition.PartitionNumber) + $AccessPath, $partition.PartitionNumber) ) -join '' ) $assignAccessPath = $false @@ -393,7 +424,7 @@ function Set-TargetResource # The volume is not formatted $volParams = @{ FileSystem = $FSFormat - Confirm = $false + Confirm = $false } if ($FSLabel) @@ -430,7 +461,7 @@ function Set-TargetResource Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($localizedData.FileSystemFormatMismatch -f ` - $AccessPath,$fileSystem,$FSFormat) + $AccessPath, $fileSystem, $FSFormat) ) -join '' ) } # if } # if @@ -445,7 +476,7 @@ function Set-TargetResource Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($localizedData.ChangingVolumeLabelMessage ` - -f $AccessPath,$FSLabel) + -f $AccessPath, $FSLabel) ) -join '' ) $volume | Set-Volume -NewFileSystemLabel $FSLabel @@ -513,7 +544,7 @@ function Test-TargetResource $DiskId, [Parameter()] - [ValidateSet('Number','UniqueId')] + [ValidateSet('Number', 'UniqueId', 'Guid')] [System.String] $DiskIdType = 'Number', @@ -530,14 +561,14 @@ function Test-TargetResource $AllocationUnitSize, [Parameter()] - [ValidateSet('NTFS','ReFS')] + [ValidateSet('NTFS', 'ReFS')] [System.String] $FSFormat = 'NTFS' ) Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " - $($localizedData.TestingDiskMessage -f $DiskIdType,$DiskId,$AccessPath) + $($localizedData.TestingDiskMessage -f $DiskIdType, $DiskId, $AccessPath) ) -join '' ) # Validate the AccessPath parameter adding a trailing slash @@ -545,22 +576,19 @@ function Test-TargetResource Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " - $($localizedData.CheckDiskInitializedMessage -f $DiskIdType,$DiskId) + $($localizedData.CheckDiskInitializedMessage -f $DiskIdType, $DiskId) ) -join '' ) - $diskIdParameter = @{ - $DiskIdType = $DiskId - } - - $disk = Get-Disk ` - @diskIdParameter ` - -ErrorAction SilentlyContinue + # Get the Disk using the identifiers supplied + $disk = Get-DiskByIdentifier ` + -DiskId $DiskId ` + -DiskIdType $DiskIdType if (-not $disk) { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " - $($localizedData.DiskNotFoundMessage -f $DiskIdType,$DiskId) + $($localizedData.DiskNotFoundMessage -f $DiskIdType, $DiskId) ) -join '' ) return $false } # if @@ -569,7 +597,7 @@ function Test-TargetResource { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " - $($localizedData.DiskNotOnlineMessage -f $DiskIdType,$DiskId) + $($localizedData.DiskNotOnlineMessage -f $DiskIdType, $DiskId) ) -join '' ) return $false } # if @@ -578,7 +606,7 @@ function Test-TargetResource { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " - $($localizedData.DiskReadOnlyMessage -f $DiskIdType,$DiskId) + $($localizedData.DiskReadOnlyMessage -f $DiskIdType, $DiskId) ) -join '' ) return $false } # if @@ -587,7 +615,7 @@ function Test-TargetResource { Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " - $($localizedData.DiskNotGPTMessage -f $DiskIdType,$DiskId,$Disk.PartitionStyle) + $($localizedData.DiskNotGPTMessage -f $DiskIdType, $DiskId, $Disk.PartitionStyle) ) -join '' ) return $false } # if @@ -597,7 +625,7 @@ function Test-TargetResource # Check if the disk has an existing partition assigned to the access path $assignedPartition = $partition | - Where-Object -Property AccessPaths -Contains -Value $AccessPath + Where-Object -Property AccessPaths -Contains -Value $AccessPath if (-not $assignedPartition) { @@ -617,17 +645,17 @@ function Test-TargetResource Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($localizedData.SizeMismatchMessage -f ` - $AccessPath,$assignedPartition.Size,$Size) + $AccessPath, $assignedPartition.Size, $Size) ) -join '' ) } # if } # if # Prepare the AccessPath used in the CIM query (replaces '\' with '\\') - $queryAccessPath = $AccessPath -replace '\\','\\' + $queryAccessPath = $AccessPath -replace '\\', '\\' $blockSize = (Get-CimInstance ` - -Query "SELECT BlockSize from Win32_Volume WHERE Name = '$queryAccessPath'" ` - -ErrorAction SilentlyContinue).BlockSize + -Query "SELECT BlockSize from Win32_Volume WHERE Name = '$queryAccessPath'" ` + -ErrorAction SilentlyContinue).BlockSize if ($blockSize -gt 0 -and $AllocationUnitSize -ne 0) { @@ -637,7 +665,7 @@ function Test-TargetResource Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($localizedData.AllocationUnitSizeMismatchMessage -f ` - $AccessPath,$($blockSize.BlockSize/1KB),$($AllocationUnitSize/1KB)) + $AccessPath, $($blockSize.BlockSize / 1KB), $($AllocationUnitSize / 1KB)) ) -join '' ) } # if } # if @@ -655,7 +683,7 @@ function Test-TargetResource Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($localizedData.FileSystemFormatMismatch -f ` - $AccessPath,$fileSystem,$FSFormat) + $AccessPath, $fileSystem, $FSFormat) ) -join '' ) } # if } # if @@ -670,7 +698,7 @@ function Test-TargetResource Write-Verbose -Message ( @( "$($MyInvocation.MyCommand): " $($localizedData.DriveLabelMismatch -f ` - $AccessPAth,$label,$FSLabel) + $AccessPAth, $label, $FSLabel) ) -join '' ) return $false } # if diff --git a/lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xDiskAccessPath/MSFT_xDiskAccessPath.schema.mof b/lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_DiskAccessPath/MSFT_DiskAccessPath.schema.mof similarity index 75% rename from lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xDiskAccessPath/MSFT_xDiskAccessPath.schema.mof rename to lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_DiskAccessPath/MSFT_DiskAccessPath.schema.mof index f792348f6..3e49fd07d 100644 --- a/lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xDiskAccessPath/MSFT_xDiskAccessPath.schema.mof +++ b/lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_DiskAccessPath/MSFT_DiskAccessPath.schema.mof @@ -1,10 +1,10 @@ -[ClassVersion("1.0.0.0"), FriendlyName("xDiskAccessPath")] -class MSFT_xDiskAccessPath : OMI_BaseResource +[ClassVersion("1.0.0.0"), FriendlyName("DiskAccessPath")] +class MSFT_DiskAccessPath : OMI_BaseResource { [Key, Description("Specifies the access path folder to the assign the disk volume to.")] String AccessPath; [Required, Description("Specifies the disk identifier for the disk to modify.")] String DiskId; - [Write, Description("Specifies the identifier type the DiskId contains. Defaults to Number."), ValueMap{"Number","UniqueId"}, Values{"Number","UniqueId"}] String DiskIdType; + [Write, Description("Specifies the identifier type the DiskId contains. Defaults to Number."), ValueMap{"Number","UniqueId","Guid"}, Values{"Number","UniqueId","Guid"}] String DiskIdType; [Write, Description("Specifies the size of new volume.")] Uint64 Size; [Write, Description("Define volume label if required.")] String FSLabel; [Write, Description("Specifies the allocation unit size to use when formatting the volume.")] Uint32 AllocationUnitSize; diff --git a/lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xDiskAccessPath/en-us/MSFT_xDiskAccessPath.strings.psd1 b/lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_DiskAccessPath/en-us/MSFT_DiskAccessPath.strings.psd1 similarity index 89% rename from lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xDiskAccessPath/en-us/MSFT_xDiskAccessPath.strings.psd1 rename to lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_DiskAccessPath/en-us/MSFT_DiskAccessPath.strings.psd1 index de5a26154..775fcc855 100644 --- a/lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xDiskAccessPath/en-us/MSFT_xDiskAccessPath.strings.psd1 +++ b/lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_DiskAccessPath/en-us/MSFT_DiskAccessPath.strings.psd1 @@ -26,6 +26,9 @@ DriveLabelMismatch = Volume assigned to access path '{0}' label '{1}' does not match expected label '{2}'. PartitionAlreadyAssignedMessage = Partition '{1}' is already assigned to access path '{0}'. MatchingPartitionNotFoundMessage = Disk with {0} '{1}' already contains paritions, but none match required size. + MatchingPartitionNoSizeMessage = Disk with {0} '{1}' already contains partitions, but size parameter is not specified. + SearchForVolumeMessage = Searching for {3} volume not assigned to path on partition '{2}' disk with {0} '{1}'. + VolumeFoundMessage = Found {3} volume not assigned to path on partition '{2}' disk with {0} '{1}'. MatchingPartitionFoundMessage = Disk with {0} '{1}' already contains paritions, and partition '{2}' matches required size. AccessPathNotFoundOnPartitionMessage = Disk with {0} '{1}' does not contain a partition assigned to access path '{2}'. diff --git a/lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xMountImage/MSFT_xMountImage.psm1 b/lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_MountImage/MSFT_MountImage.psm1 similarity index 99% rename from lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xMountImage/MSFT_xMountImage.psm1 rename to lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_MountImage/MSFT_MountImage.psm1 index 061857c47..eb41b7a6f 100644 --- a/lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xMountImage/MSFT_xMountImage.psm1 +++ b/lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_MountImage/MSFT_MountImage.psm1 @@ -19,7 +19,7 @@ Import-Module -Name (Join-Path -Path $modulePath ` # Import Localization Strings $localizedData = Get-LocalizedData ` - -ResourceName 'MSFT_xMountImage' ` + -ResourceName 'MSFT_MountImage' ` -ResourcePath (Split-Path -Parent $Script:MyInvocation.MyCommand.Path) <# diff --git a/lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xMountImage/MSFT_xMountImage.schema.mof b/lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_MountImage/MSFT_MountImage.schema.mof similarity index 90% rename from lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xMountImage/MSFT_xMountImage.schema.mof rename to lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_MountImage/MSFT_MountImage.schema.mof index 84c671354..59ca6bbb0 100644 --- a/lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xMountImage/MSFT_xMountImage.schema.mof +++ b/lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_MountImage/MSFT_MountImage.schema.mof @@ -1,6 +1,6 @@ -[ClassVersion("1.0.0.0"), FriendlyName("xMountImage")] -class MSFT_xMountImage : OMI_BaseResource +[ClassVersion("1.0.0.0"), FriendlyName("MountImage")] +class MSFT_MountImage : OMI_BaseResource { [Key, Description("Specifies the path of the VHD or ISO file.")] String ImagePath; [Write, Description("Specifies the drive letter to mount this VHD or ISO to.")] String DriveLetter; diff --git a/lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xMountImage/en-us/MSFT_xMountImage.strings.psd1 b/lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_MountImage/en-us/MSFT_MountImage.strings.psd1 similarity index 100% rename from lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xMountImage/en-us/MSFT_xMountImage.strings.psd1 rename to lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_MountImage/en-us/MSFT_MountImage.strings.psd1 diff --git a/lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_OpticalDiskDriveLetter/MSFT_OpticalDiskDriveLetter.psm1 b/lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_OpticalDiskDriveLetter/MSFT_OpticalDiskDriveLetter.psm1 new file mode 100644 index 000000000..1248cb7fc --- /dev/null +++ b/lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_OpticalDiskDriveLetter/MSFT_OpticalDiskDriveLetter.psm1 @@ -0,0 +1,373 @@ +# Suppressed as per PSSA Rule Severity guidelines for unit/integration tests: +# https://github.com/PowerShell/DscResources/blob/master/PSSARuleSeverities.md +[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseShouldProcessForStateChangingFunctions', '')] +param () + +$modulePath = Join-Path -Path (Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent) -ChildPath 'Modules' + +# Import the Storage Common Modules +Import-Module -Name (Join-Path -Path $modulePath ` + -ChildPath (Join-Path -Path 'StorageDsc.Common' ` + -ChildPath 'StorageDsc.Common.psm1')) + +# Import the Storage Resource Helper Module +Import-Module -Name (Join-Path -Path $modulePath ` + -ChildPath (Join-Path -Path 'StorageDsc.ResourceHelper' ` + -ChildPath 'StorageDsc.ResourceHelper.psm1')) + +# Import Localization Strings +$localizedData = Get-LocalizedData ` + -ResourceName 'MSFT_OpticalDiskDriveLetter' ` + -ResourcePath (Split-Path -Parent $Script:MyInvocation.MyCommand.Path) + +<# + .SYNOPSIS + This helper function returns a hashtable containing the current + drive letter assigned to the optical disk in the system matching + the disk number. + + If the drive exists but is not mounted to a drive letter then + the DriveLetter will be empty, but the DeviceId will contain the + DeviceId representing the optical disk. + + If there are no optical disks found in the system an exception + will be thrown. + + .PARAMETER DiskId + Specifies the optical disk number for the disk to return the drive + letter of. + + .NOTES + The Caption and DeviceID properties are checked to avoid + mounted ISO images in Windows 2012+ and Windows 10. The + device ID is required because a CD/DVD in a Hyper-V virtual + machine has the same caption as a mounted ISO. + + Example DeviceID for a virtual drive in a Hyper-V VM - SCSI\CDROM&VEN_MSFT&PROD_VIRTUAL_DVD-ROM\000006 + Example DeviceID for a mounted ISO in a Hyper-V VM - SCSI\CDROM&VEN_MSFT&PROD_VIRTUAL_DVD-ROM\2&1F4ADFFE&0&000002 +#> +function Get-OpticalDiskDriveLetter +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $DiskId + ) + + $driveLetter = $null + + Write-Verbose -Message ( @( + "$($MyInvocation.MyCommand): " + $($localizedData.UsingGetCimInstanceToFetchDriveLetter -f $DiskId) + ) -join '' ) + + # Get the optical disk matching the Id + $opticalDisks = Get-CimInstance -ClassName Win32_CDROMDrive | + Where-Object -FilterScript { + -not ( + $_.Caption -eq 'Microsoft Virtual DVD-ROM' -and + ($_.DeviceID.Split('\')[-1]).Length -gt 10 + ) + } + + $deviceId = '' + + if ($opticalDisks) + { + <# + To behave in a similar fashion to the other xStorage resources the + DiskId represents the number of the optical disk in the system. + However as these are returned as an array of 0..x elements then + subtract one from the DiskId to get the actual optical disk number + that is required. + #> + $opticalDisk = $opticalDisks[$DiskId - 1] + + if ($opticalDisk) + { + try + { + # Make sure the current DriveLetter is an actual drive letter + $driveLetter = Assert-DriveLetterValid -DriveLetter $opticalDisk.Drive -Colon + } + catch + { + # Optical drive exists but is not mounted to a drive letter + $driveLetter = '' + + Write-Verbose -Message ( @( + "$($MyInvocation.MyCommand): " + $($localizedData.OpticalDiskNotAssignedDriveLetter -f $DiskId) + ) -join '' ) + } + $deviceId = $opticalDisk.Drive + } + } + + if ($null -eq $driveLetter) + { + New-InvalidArgumentException ` + -Message ($localizedData.NoOpticalDiskDriveError -f $DiskId) ` + -ArgumentName 'DiskId' + } + + return @{ + DriveLetter = $driveLetter + DeviceId = $deviceId + } +} + +<# + .SYNOPSIS + Returns the current drive letter assigned to the optical disk. + + .PARAMETER DiskId + Specifies the optical disk number for the disk to assign the drive + letter to. + + .PARAMETER DriveLetter + Specifies the drive letter to assign to the optical disk. Can be a + single letter, optionally followed by a colon. This value is ignored + if Ensure is set to Absent. +#> +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $DiskId, + + [Parameter(Mandatory = $true)] + [System.String] + $DriveLetter + ) + + $ensure = 'Absent' + + # Get the drive letter assigned to the optical disk + $currentDriveInfo = Get-OpticalDiskDriveLetter -DiskId $DiskId + $currentDriveLetter = $currentDriveInfo.DriveLetter + + if ([System.String]::IsNullOrWhiteSpace($currentDriveLetter)) + { + Write-Verbose -Message ( @( + "$($MyInvocation.MyCommand): " + $($localizedData.OpticalDiskNotAssignedDriveLetter -f $DiskId) + ) -join '' ) + } + else + { + Write-Verbose -Message ( @( + "$($MyInvocation.MyCommand): " + $($localizedData.OpticalDiskAssignedDriveLetter -f $DiskId, $DriveLetter) + ) -join '' ) + + $Ensure = 'Present' + } + + $returnValue += @{ + DiskId = $DiskId + DriveLetter = $currentDriveLetter + Ensure = $ensure + } + + return $returnValue +} # Get-TargetResource + +<# + .SYNOPSIS + Sets the drive letter of an optical disk. + + .PARAMETER DiskId + Specifies the optical disk number for the disk to assign the drive + letter to. + + .PARAMETER DriveLetter + Specifies the drive letter to assign to the optical disk. Can be a + single letter, optionally followed by a colon. This value is ignored + if Ensure is set to Absent. + + .PARAMETER Ensure + Determines whether a drive letter should be assigned to the + optical disk. Defaults to 'Present'. +#> +function Set-TargetResource +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $DiskId, + + [Parameter(Mandatory = $true)] + [System.String] + $DriveLetter, + + [Parameter()] + [ValidateSet('Present', 'Absent')] + [System.String] + $Ensure = 'Present' + ) + + # Allow use of drive letter without colon + $DriveLetter = Assert-DriveLetterValid -DriveLetter $DriveLetter -Colon + + # Get the drive letter assigned to the optical disk + $currentDriveInfo = Get-OpticalDiskDriveLetter -DiskId $DiskId + $currentDriveLetter = $currentDriveInfo.DriveLetter + + if ([System.String]::IsNullOrWhiteSpace($currentDriveLetter)) + { + <# + If the current drive letter is empty then the volume must be looked up by DeviceId + The DeviceId in the volume will show as \\?\Volume{bba1802b-e7a1-11e3-824e-806e6f6e6963}\ + So we need to change the currentDriveLetter to match this value when we set the drive letter + #> + $deviceId = $currentDriveInfo.DeviceId + + $volume = Get-CimInstance ` + -ClassName Win32_Volume ` + -Filter "DeviceId = '\\\\?\\$deviceId\\'" + } + else + { + $volume = Get-CimInstance ` + -ClassName Win32_Volume ` + -Filter "DriveLetter = '$currentDriveLetter'" + } + + # Does the Drive Letter need to be added or removed + if ($Ensure -eq 'Absent') + { + Write-Verbose -Message ( @( + "$($MyInvocation.MyCommand): " + $($localizedData.AttemptingToRemoveDriveLetter -f $diskId, $currentDriveLetter) + ) -join '' ) + + $volume | Set-CimInstance -Property @{ DriveLetter = $null } + } + else + { + Write-Verbose -Message ( @( + "$($MyInvocation.MyCommand): " + $($localizedData.AttemptingToSetDriveLetter -f $diskId, $currentDriveLetter, $DriveLetter) + ) -join '' ) + + $volume | Set-CimInstance -Property @{ DriveLetter = $DriveLetter } + } +} # Set-TargetResource + +<# + .SYNOPSIS + Tests the disk letter assigned to an optical disk is correct. + + .PARAMETER DiskId + Specifies the optical disk number for the disk to assign the drive + letter to. + + .PARAMETER DriveLetter + Specifies the drive letter to assign to the optical disk. Can be a + single letter, optionally followed by a colon. This value is ignored + if Ensure is set to Absent. + + .PARAMETER Ensure + Determines whether a drive letter should be assigned to the + optical disk. Defaults to 'Present'. +#> +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $DiskId, + + [Parameter(Mandatory = $true)] + [System.String] + $DriveLetter, + + [Parameter()] + [ValidateSet('Present', 'Absent')] + [System.String] + $Ensure = 'Present' + ) + + $desiredConfigurationMatch = $true + + # Allow use of drive letter without colon + $DriveLetter = Assert-DriveLetterValid -DriveLetter $DriveLetter -Colon + + # Get the drive letter assigned to the optical disk + $currentDriveInfo = Get-OpticalDiskDriveLetter -DiskId $DiskId + $currentDriveLetter = $currentDriveInfo.DriveLetter + + if ($Ensure -eq 'Absent') + { + # The Drive Letter should be absent from the optical disk + if ([System.String]::IsNullOrWhiteSpace($currentDriveLetter)) + { + Write-Verbose -Message ( @( + "$($MyInvocation.MyCommand): " + $($localizedData.DriveLetterDoesNotExistAndShouldNot -f $DiskId) + ) -join '' ) + } + else + { + # The Drive Letter needs to be dismounted + Write-Verbose -Message ( @( + "$($MyInvocation.MyCommand): " + $($localizedData.DriveLetterExistsButShouldNot -f $DiskId, $currentDriveLetter) + ) -join '' ) + + $desiredConfigurationMatch = $false + } + } + else + { + if ($currentDriveLetter -eq $DriveLetter) + { + # The optical disk drive letter is already set correctly + Write-Verbose -Message ( @( + "$($MyInvocation.MyCommand): " + $($localizedData.DriverLetterExistsAndIsCorrect -f $DiskId, $DriveLetter) + ) -join '' ) + } + else + { + # Is a desired drive letter already assigned to a different drive? + $existingVolume = Get-CimInstance ` + -ClassName Win32_Volume ` + -Filter "DriveLetter = '$DriveLetter'" + + if ($existingVolume) + { + # The desired drive letter is already assigned to another drive - can't proceed + New-InvalidOperationException ` + -Message $($localizedData.DriveLetterAssignedToAnotherDrive -f $DriveLetter) + } + else + { + # The optical drive letter needs to be changed + Write-Verbose -Message ( @( + "$($MyInvocation.MyCommand): " + $($localizedData.DriverLetterExistsAndIsNotCorrect -f $DiskId, $currentDriveLetter, $DriveLetter) + ) -join '' ) + + $desiredConfigurationMatch = $false + } + } + } + + return $desiredConfigurationMatch +} + +Export-ModuleMember -Function *-TargetResource diff --git a/lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_OpticalDiskDriveLetter/MSFT_OpticalDiskDriveLetter.schema.mof b/lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_OpticalDiskDriveLetter/MSFT_OpticalDiskDriveLetter.schema.mof new file mode 100644 index 000000000..14fa06492 --- /dev/null +++ b/lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_OpticalDiskDriveLetter/MSFT_OpticalDiskDriveLetter.schema.mof @@ -0,0 +1,8 @@ + +[ClassVersion("1.0.0.0"), FriendlyName("OpticalDiskDriveLetter")] +class MSFT_OpticalDiskDriveLetter : OMI_BaseResource +{ + [Key, Description("Specifies the optical disk number for the disk to assign the drive letter to.")] String DiskId; + [Required, Description("Specifies the drive letter to assign to the optical disk. Can be a single letter, optionally followed by a colon. This value is ignored if Ensure is set to Absent.")] String DriveLetter; + [Write, Description("Determines whether a drive letter should be assigned to the optical disk. Defaults to 'Present'."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; +}; diff --git a/lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_OpticalDiskDriveLetter/en-us/MSFT_OpticalDiskDriveLetter.strings.psd1 b/lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_OpticalDiskDriveLetter/en-us/MSFT_OpticalDiskDriveLetter.strings.psd1 new file mode 100644 index 000000000..0760466bd --- /dev/null +++ b/lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_OpticalDiskDriveLetter/en-us/MSFT_OpticalDiskDriveLetter.strings.psd1 @@ -0,0 +1,15 @@ +ConvertFrom-StringData @' + UsingGetCimInstanceToFetchDriveLetter = Using Get-CimInstance to get the drive letter of optical disk {0} in the system. + OpticalDiskAssignedDriveLetter = The optical disk {0} is currently assigned drive letter '{1}'. + OpticalDiskNotAssignedDriveLetter = The optical disk {0} is not currently assigned a drive letter. + NoOpticalDiskDriveError = The optical disk {0} could not be found in the system, so this resource has nothing to do. This resource does not change the drive letter of mounted ISOs. + + AttemptingToSetDriveLetter = The optical disk {0} drive letter is '{1}', attempting to set to '{2}'. + AttemptingToRemoveDriveLetter = The optical disk {0} drive letter is '{1}', attempting to remove it. + + DriveLetterDoesNotExistAndShouldNot = The optical disk {0} does not have a drive letter assigned. Change not required. + DriveLetterExistsButShouldNot = The optical disk {0} is assigned the drive letter '{1}' which should be removed. Change required. + DriverLetterExistsAndIsCorrect = The optical disk {0} is assigned the drive letter '{1}' which is correct. Change not required. + DriveLetterAssignedToAnotherDrive = Drive letter '{0}' is already present but assigned to a another volume. Change can not proceed. + DriverLetterExistsAndIsNotCorrect = The optical disk {0} is assigned the drive letter '{1}' but should be '{2}'. Change required. +'@ diff --git a/lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xWaitForDisk/MSFT_xWaitForDisk.psm1 b/lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_WaitForDisk/MSFT_WaitForDisk.psm1 similarity index 92% rename from lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xWaitForDisk/MSFT_xWaitForDisk.psm1 rename to lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_WaitForDisk/MSFT_WaitForDisk.psm1 index ab8af9f14..e18a71ff1 100644 --- a/lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xWaitForDisk/MSFT_xWaitForDisk.psm1 +++ b/lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_WaitForDisk/MSFT_WaitForDisk.psm1 @@ -17,7 +17,7 @@ Import-Module -Name (Join-Path -Path $modulePath ` # Import Localization Strings $localizedData = Get-LocalizedData ` - -ResourceName 'MSFT_xWaitForDisk' ` + -ResourceName 'MSFT_WaitForDisk' ` -ResourcePath (Split-Path -Parent $Script:MyInvocation.MyCommand.Path) <# @@ -47,7 +47,7 @@ function Get-TargetResource $DiskId, [Parameter()] - [ValidateSet('Number','UniqueId')] + [ValidateSet('Number','UniqueId','Guid')] [System.String] $DiskIdType = 'Number', @@ -100,7 +100,7 @@ function Set-TargetResource $DiskId, [Parameter()] - [ValidateSet('Number','UniqueId')] + [ValidateSet('Number','UniqueId','Guid')] [System.String] $DiskIdType = 'Number', @@ -120,15 +120,14 @@ function Set-TargetResource $diskFound = $false - $diskIdParameter = @{ - $DiskIdType = $DiskId - } for ($count = 0; $count -lt $RetryCount; $count++) { - $disk = Get-Disk ` - @diskIdParameter ` - -ErrorAction SilentlyContinue + # Get the Disk using the identifiers supplied + $disk = Get-DiskByIdentifier ` + -DiskId $DiskId ` + -DiskIdType $DiskIdType + if ($disk) { Write-Verbose -Message ( @( @@ -184,7 +183,7 @@ function Test-TargetResource $DiskId, [Parameter()] - [ValidateSet('Number','UniqueId')] + [ValidateSet('Number','UniqueId','Guid')] [System.String] $DiskIdType = 'Number', @@ -202,13 +201,10 @@ function Test-TargetResource $($localizedData.CheckingForDiskStatusMessage -f $DiskIdType,$DiskId) ) -join '' ) - $diskIdParameter = @{ - $DiskIdType = $DiskId - } - - $disk = Get-Disk ` - @diskIdParameter ` - -ErrorAction SilentlyContinue + # Get the Disk using the identifiers supplied + $disk = Get-DiskByIdentifier ` + -DiskId $DiskId ` + -DiskIdType $DiskIdType if ($disk) { diff --git a/lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xWaitForDisk/MSFT_xWaitForDisk.schema.mof b/lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_WaitForDisk/MSFT_WaitForDisk.schema.mof similarity index 64% rename from lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xWaitForDisk/MSFT_xWaitForDisk.schema.mof rename to lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_WaitForDisk/MSFT_WaitForDisk.schema.mof index 0d8055520..ed998fbb8 100644 --- a/lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xWaitForDisk/MSFT_xWaitForDisk.schema.mof +++ b/lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_WaitForDisk/MSFT_WaitForDisk.schema.mof @@ -1,9 +1,9 @@ -[ClassVersion("1.0.0.0"), FriendlyName("xWaitForDisk")] -class MSFT_xWaitForDisk : OMI_BaseResource +[ClassVersion("1.0.0.0"), FriendlyName("WaitForDisk")] +class MSFT_WaitForDisk : OMI_BaseResource { [Key, Description("Specifies the disk identifier for the disk to wait for.")] String DiskId; - [Write, Description("Specifies the identifier type the DiskId contains. Defaults to Number."), ValueMap{"Number","UniqueId"}, Values{"Number","UniqueId"}] String DiskIdType; + [Write, Description("Specifies the identifier type the DiskId contains. Defaults to Number."), ValueMap{"Number","UniqueId","Guid"}, Values{"Number","UniqueId","Guid"}] String DiskIdType; [Write, Description("Specifies the number of seconds to wait for the disk to become available.")] Uint32 RetryIntervalSec; [Write, Description("The number of times to loop the retry interval while waiting for the disk.")] Uint32 RetryCount; }; diff --git a/lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xWaitForDisk/en-us/MSFT_xWaitForDisk.strings.psd1 b/lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_WaitForDisk/en-us/MSFT_WaitForDisk.strings.psd1 similarity index 100% rename from lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xWaitForDisk/en-us/MSFT_xWaitForDisk.strings.psd1 rename to lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_WaitForDisk/en-us/MSFT_WaitForDisk.strings.psd1 diff --git a/lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xWaitForVolume/MSFT_xWaitForVolume.psm1 b/lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_WaitForVolume/MSFT_WaitForVolume.psm1 similarity index 99% rename from lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xWaitForVolume/MSFT_xWaitForVolume.psm1 rename to lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_WaitForVolume/MSFT_WaitForVolume.psm1 index eafb9d3b0..5e8d6cb1b 100644 --- a/lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xWaitForVolume/MSFT_xWaitForVolume.psm1 +++ b/lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_WaitForVolume/MSFT_WaitForVolume.psm1 @@ -17,7 +17,7 @@ Import-Module -Name (Join-Path -Path $modulePath ` # Import Localization Strings $localizedData = Get-LocalizedData ` - -ResourceName 'MSFT_xWaitForVolume' ` + -ResourceName 'MSFT_WaitForVolume' ` -ResourcePath (Split-Path -Parent $Script:MyInvocation.MyCommand.Path) <# diff --git a/lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xWaitForVolume/MSFT_xWaitForVolume.schema.mof b/lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_WaitForVolume/MSFT_WaitForVolume.schema.mof similarity index 77% rename from lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xWaitForVolume/MSFT_xWaitForVolume.schema.mof rename to lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_WaitForVolume/MSFT_WaitForVolume.schema.mof index 5c2fce886..2eada7519 100644 --- a/lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xWaitForVolume/MSFT_xWaitForVolume.schema.mof +++ b/lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_WaitForVolume/MSFT_WaitForVolume.schema.mof @@ -1,6 +1,6 @@ -[ClassVersion("1.0.0.0"), FriendlyName("xWaitForVolume")] -class MSFT_xWaitForVolume : OMI_BaseResource +[ClassVersion("1.0.0.0"), FriendlyName("WaitForVolume")] +class MSFT_WaitForVolume : OMI_BaseResource { [Key, Description("Specifies the drive letter of the volume to wait for.")] String DriveLetter; [Write, Description("Specifies the number of seconds to wait for the volume to become available.")] Uint32 RetryIntervalSec; diff --git a/lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xWaitForVolume/en-us/MSFT_xWaitForVolume.strings.psd1 b/lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_WaitForVolume/en-us/MSFT_WaitForVolume.strings.psd1 similarity index 100% rename from lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xWaitForVolume/en-us/MSFT_xWaitForVolume.strings.psd1 rename to lib/puppet_x/dsc_resources/StorageDsc/DSCResources/MSFT_WaitForVolume/en-us/MSFT_WaitForVolume.strings.psd1 diff --git a/lib/puppet_x/dsc_resources/xStorage/LICENSE b/lib/puppet_x/dsc_resources/StorageDsc/LICENSE similarity index 96% rename from lib/puppet_x/dsc_resources/xStorage/LICENSE rename to lib/puppet_x/dsc_resources/StorageDsc/LICENSE index 5f178f939..6c8da8ff3 100644 --- a/lib/puppet_x/dsc_resources/xStorage/LICENSE +++ b/lib/puppet_x/dsc_resources/StorageDsc/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2015 Michael Greene +Copyright (c) 2017 Microsoft Corporation Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/lib/puppet_x/dsc_resources/xStorage/Modules/StorageDsc.Common/StorageDsc.Common.psm1 b/lib/puppet_x/dsc_resources/StorageDsc/Modules/StorageDsc.Common/StorageDsc.Common.psm1 similarity index 54% rename from lib/puppet_x/dsc_resources/xStorage/Modules/StorageDsc.Common/StorageDsc.Common.psm1 rename to lib/puppet_x/dsc_resources/StorageDsc/Modules/StorageDsc.Common/StorageDsc.Common.psm1 index 3b29f1d23..bf77ee7bf 100644 --- a/lib/puppet_x/dsc_resources/xStorage/Modules/StorageDsc.Common/StorageDsc.Common.psm1 +++ b/lib/puppet_x/dsc_resources/StorageDsc/Modules/StorageDsc.Common/StorageDsc.Common.psm1 @@ -1,4 +1,4 @@ -# Import the Networking Resource Helper Module +# Import the Networking Resource Helper Module Import-Module -Name (Join-Path -Path (Split-Path -Path $PSScriptRoot -Parent) ` -ChildPath (Join-Path -Path 'StorageDsc.ResourceHelper' ` -ChildPath 'StorageDsc.ResourceHelper.psm1')) @@ -33,20 +33,24 @@ function Assert-DriveLetterValid $Colon ) - $Matches = @([regex]::matches($DriveLetter, '^([A-Za-z]):?$', 'IgnoreCase')) - if (-not $Matches) + $matches = @([regex]::matches($DriveLetter, '^([A-Za-z]):?$', 'IgnoreCase')) + + if (-not $matches) { # DriveLetter format is invalid New-InvalidArgumentException ` -Message $($LocalizedData.InvalidDriveLetterFormatError -f $DriveLetter) ` -ArgumentName 'DriveLetter' } + # This is the drive letter without a colon - $DriveLetter = $Matches.Groups[1].Value + $DriveLetter = $matches.Groups[1].Value + if ($Colon) { $DriveLetter = $DriveLetter + ':' } # if + return $DriveLetter } # end function Assert-DriveLetterValid @@ -104,4 +108,89 @@ function Assert-AccessPathValid return $AccessPath } # end function Assert-AccessPathValid -Export-ModuleMember -Function @( 'Assert-DriveLetterValid', 'Assert-AccessPathValid' ) + +<# + .SYNOPSIS + Retrieves a Disk object matching the disk Id and Id type + provided. + + .PARAMETER DiskId + Specifies the disk identifier for the disk to retrieve. + + .PARAMETER DiskIdType + Specifies the identifier type the DiskId contains. Defaults to Number. +#> +function Get-DiskByIdentifier +{ + [CmdletBinding()] + [OutputType([Microsoft.Management.Infrastructure.CimInstance])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $DiskId, + + [Parameter()] + [ValidateSet('Number','UniqueId','Guid')] + [System.String] + $DiskIdType = 'Number' + ) + + if ($DiskIdType -eq 'Guid') + { + # The Disk Id requested uses a Guid so have to get all disks and filter + $disk = Get-Disk ` + -ErrorAction SilentlyContinue | + Where-Object -Property Guid -EQ $DiskId + } + else + { + $diskIdParameter = @{ + $DiskIdType = $DiskId + } + + $disk = Get-Disk ` + @diskIdParameter ` + -ErrorAction SilentlyContinue + } + + return $disk +} # end function Get-DiskByIdentifier + +<# + .SYNOPSIS + Tests if any of the access paths from a partition are assigned + to a local path. + + .PARAMETER AccessPath + Specifies the access paths that are assigned to the partition. +#> +function Test-AccessPathAssignedToLocal +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [System.String[]] + $AccessPath + ) + + $accessPathAssigned = $false + foreach ($path in $AccessPath) + { + if ($path -match '[a-zA-Z]:\\') + { + $accessPathAssigned = $true + break + } + } + + return $accessPathAssigned +} # end function Test-AccessPathLocal + +Export-ModuleMember -Function ` + Assert-DriveLetterValid, ` + Assert-AccessPathValid, ` + Get-DiskByIdentifier, + Test-AccessPathAssignedToLocal diff --git a/lib/puppet_x/dsc_resources/xStorage/Modules/StorageDsc.Common/en-us/StorageDsc.Common.strings.psd1 b/lib/puppet_x/dsc_resources/StorageDsc/Modules/StorageDsc.Common/en-us/StorageDsc.Common.strings.psd1 similarity index 100% rename from lib/puppet_x/dsc_resources/xStorage/Modules/StorageDsc.Common/en-us/StorageDsc.Common.strings.psd1 rename to lib/puppet_x/dsc_resources/StorageDsc/Modules/StorageDsc.Common/en-us/StorageDsc.Common.strings.psd1 diff --git a/lib/puppet_x/dsc_resources/xStorage/Modules/StorageDsc.ResourceHelper/StorageDsc.ResourceHelper.psm1 b/lib/puppet_x/dsc_resources/StorageDsc/Modules/StorageDsc.ResourceHelper/StorageDsc.ResourceHelper.psm1 similarity index 99% rename from lib/puppet_x/dsc_resources/xStorage/Modules/StorageDsc.ResourceHelper/StorageDsc.ResourceHelper.psm1 rename to lib/puppet_x/dsc_resources/StorageDsc/Modules/StorageDsc.ResourceHelper/StorageDsc.ResourceHelper.psm1 index f4d2fe683..5cb0d29af 100644 --- a/lib/puppet_x/dsc_resources/xStorage/Modules/StorageDsc.ResourceHelper/StorageDsc.ResourceHelper.psm1 +++ b/lib/puppet_x/dsc_resources/StorageDsc/Modules/StorageDsc.ResourceHelper/StorageDsc.ResourceHelper.psm1 @@ -1,4 +1,4 @@ -<# +<# .SYNOPSIS Tests if the current machine is a Nano server. #> diff --git a/lib/puppet_x/dsc_resources/xStorage/xStorage.psd1 b/lib/puppet_x/dsc_resources/StorageDsc/StorageDsc.psd1 similarity index 75% rename from lib/puppet_x/dsc_resources/xStorage/xStorage.psd1 rename to lib/puppet_x/dsc_resources/StorageDsc/StorageDsc.psd1 index d9a63e9d2..29f6dfa9e 100644 --- a/lib/puppet_x/dsc_resources/xStorage/xStorage.psd1 +++ b/lib/puppet_x/dsc_resources/StorageDsc/StorageDsc.psd1 @@ -1,5 +1,5 @@ # -# Module manifest for module 'xStorage' +# Module manifest for module 'StorageDsc' # # Generated on: 6/14/2015 # @@ -10,7 +10,7 @@ # RootModule = '' # Version number of this module. -ModuleVersion = '3.2.0.0' +ModuleVersion = '4.0.0.0' # ID used to uniquely identify this module GUID = '00d73ca1-58b5-46b7-ac1a-5bfcf5814faf' @@ -22,7 +22,7 @@ Author = 'PowerShell DSC' CompanyName = 'Microsoft Corporation' # Copyright statement for this module -Copyright = '2015' +Copyright = '2018' # Description of the functionality provided by this module Description = 'This module contains all resources related to the PowerShell Storage module, or pertaining to disk management.' @@ -93,27 +93,25 @@ PrivateData = @{ Tags = @('DesiredStateConfiguration', 'DSC', 'DSCResourceKit', 'DSCResource') # A URL to the license for this module. - LicenseUri = 'https://github.com/PowerShell/xStorage/blob/master/LICENSE' + LicenseUri = 'https://github.com/PowerShell/StorageDsc/blob/master/LICENSE' # A URL to the main website for this project. - ProjectUri = 'https://github.com/PowerShell/xStorage' + ProjectUri = 'https://github.com/PowerShell/StorageDsc' # A URL to an icon representing this module. # IconUri = '' # ReleaseNotes of this module - ReleaseNotes = '- xDisk: - - Fix error message when new partition does not become writable before timeout. - - Removed unneeded timeout initialization code. -- xDiskAccessPath: - - Fix error message when new partition does not become writable before timeout. - - Removed unneeded timeout initialization code. - - Fix error when used on Windows Server 2012 R2 - See [Issue 102](https://github.com/PowerShell/xStorage/issues/102). -- Added the VS Code PowerShell extension formatting settings that cause PowerShell - files to be formatted as per the DSC Resource kit style guidelines. -- Removed requirement on Hyper-V PowerShell module to execute integration tests. -- xMountImage: - - Fix error when mounting VHD on Windows Server 2012 R2 - See [Issue 105](https://github.com/PowerShell/xStorage/issues/105) + ReleaseNotes = '- BREAKING CHANGE: + - Renamed xStorage to StorageDsc + - Renamed MSFT_xDisk to MSFT_Disk + - Renamed MSFT_xDiskAccessPath to MSFT_DiskAccessPath + - Renamed MSFT_xMountImage to MSFT_MountImage + - Renamed MSFT_xOpticalDiskDriveLetter to MSFT_OpticalDiskDriveLetter + - Renamed MSFT_xWaitForDisk to MSFT_WaitForDisk + - Renamed MSFT_xWaitForVolume to MSFT_WaitforVolume + - Deleted xStorage folder under StorageDsc/Modules + - See [Issue 129](https://github.com/PowerShell/xStorage/issues/129) ' @@ -135,3 +133,6 @@ PrivateData = @{ + + + diff --git a/types.md b/types.md index 0898aae47..75c918bcb 100644 --- a/types.md +++ b/types.md @@ -116,6 +116,42 @@ dsc_spwebapplicationappdomain | [SPWebApplicationAppDomain](https://github.com/p dsc_spwebapplicationextension | [SPWebApplicationExtension](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/SharePointDsc/DSCResources/MSFT_SPWebApplicationExtension) | import/dsc_resources/SharePointDsc/DSCResources/MSFT_SPWebApplicationExtension/MSFT_SPWebApplicationExtension.schema.mof dsc_spwordautomationserviceapp | [SPWordAutomationServiceApp](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/SharePointDsc/DSCResources/MSFT_SPWordAutomationServiceApp) | import/dsc_resources/SharePointDsc/DSCResources/MSFT_SPWordAutomationServiceApp/MSFT_SPWordAutomationServiceApp.schema.mof dsc_spworkmanagementserviceapp | [SPWorkManagementServiceApp](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/SharePointDsc/DSCResources/MSFT_SPWorkManagementServiceApp) | import/dsc_resources/SharePointDsc/DSCResources/MSFT_SPWorkManagementServiceApp/MSFT_SPWorkManagementServiceApp.schema.mof +dsc_sqlag | [SqlAG](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAG) | import/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAG/MSFT_SqlAG.schema.mof +dsc_sqlagdatabase | [SqlAGDatabase](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAGDatabase) | import/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAGDatabase/MSFT_SqlAGDatabase.schema.mof +dsc_sqlaglistener | [SqlAGListener](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAGListener) | import/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAGListener/MSFT_SqlAGListener.schema.mof +dsc_sqlagreplica | [SqlAGReplica](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAGReplica) | import/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAGReplica/MSFT_SqlAGReplica.schema.mof +dsc_sqlalias | [SqlAlias](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAlias) | import/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAlias/MSFT_SqlAlias.schema.mof +dsc_sqlalwaysonservice | [SqlAlwaysOnService](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAlwaysOnService) | import/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAlwaysOnService/MSFT_SqlAlwaysOnService.schema.mof +dsc_sqldatabase | [SqlDatabase](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabase) | import/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabase/MSFT_SqlDatabase.schema.mof +dsc_sqldatabasedefaultlocation | [SqlDatabaseDefaultLocation](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseDefaultLocation) | import/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseDefaultLocation/MSFT_SqlDatabaseDefaultLocation.schema.mof +dsc_sqldatabaseowner | [SqlDatabaseOwner](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseOwner) | import/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseOwner/MSFT_SqlDatabaseOwner.schema.mof +dsc_sqldatabasepermission | [SqlDatabasePermission](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabasePermission) | import/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabasePermission/MSFT_SqlDatabasePermission.schema.mof +dsc_sqldatabaserecoverymodel | [SqlDatabaseRecoveryModel](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseRecoveryModel) | import/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseRecoveryModel/MSFT_SqlDatabaseRecoveryModel.schema.mof +dsc_sqldatabaserole | [SqlDatabaseRole](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseRole) | import/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseRole/MSFT_SqlDatabaseRole.schema.mof +dsc_sqlrs | [SqlRS](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlRS) | import/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlRS/MSFT_SqlRS.schema.mof +dsc_sqlscript | [SqlScript](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlScript) | import/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlScript/MSFT_SqlScript.schema.mof +dsc_sqlserverconfiguration | [SqlServerConfiguration](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerConfiguration) | import/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerConfiguration/MSFT_SqlServerConfiguration.schema.mof +dsc_sqlserverdatabasemail | [SqlServerDatabaseMail](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerDatabaseMail) | import/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerDatabaseMail/MSFT_SqlServerDatabaseMail.schema.mof +dsc_sqlserverendpoint | [SqlServerEndpoint](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerEndpoint) | import/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerEndpoint/MSFT_SqlServerEndpoint.schema.mof +dsc_sqlserverendpointpermission | [SqlServerEndpointPermission](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerEndpointPermission) | import/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerEndpointPermission/MSFT_SqlServerEndpointPermission.schema.mof +dsc_sqlserverendpointstate | [SqlServerEndpointState](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerEndpointState) | import/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerEndpointState/MSFT_SqlServerEndpointState.schema.mof +dsc_sqlserverlogin | [SqlServerLogin](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerLogin) | import/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerLogin/MSFT_SqlServerLogin.schema.mof +dsc_sqlservermaxdop | [SqlServerMaxDop](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerMaxDop) | import/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerMaxDop/MSFT_SqlServerMaxDop.schema.mof +dsc_sqlservermemory | [SqlServerMemory](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerMemory) | import/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerMemory/MSFT_SqlServerMemory.schema.mof +dsc_sqlservernetwork | [SqlServerNetwork](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerNetwork) | import/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerNetwork/MSFT_SqlServerNetwork.schema.mof +dsc_sqlserverpermission | [SqlServerPermission](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerPermission) | import/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerPermission/MSFT_SqlServerPermission.schema.mof +dsc_sqlserverreplication | [SqlServerReplication](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerReplication) | import/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerReplication/MSFT_SqlServerReplication.schema.mof +dsc_sqlserverrole | [SqlServerRole](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerRole) | import/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerRole/MSFT_SqlServerRole.schema.mof +dsc_sqlserviceaccount | [SqlServiceAccount](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServiceAccount) | import/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServiceAccount/MSFT_SqlServiceAccount.schema.mof +dsc_sqlsetup | [SqlSetup](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlSetup) | import/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlSetup/MSFT_SqlSetup.schema.mof +dsc_sqlwaitforag | [SqlWaitForAG](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlWaitForAG) | import/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlWaitForAG/MSFT_SqlWaitForAG.schema.mof +dsc_sqlwindowsfirewall | [SqlWindowsFirewall](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlWindowsFirewall) | import/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlWindowsFirewall/MSFT_SqlWindowsFirewall.schema.mof +dsc_disk | [Disk](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/StorageDsc/DSCResources/MSFT_Disk) | import/dsc_resources/StorageDsc/DSCResources/MSFT_Disk/MSFT_Disk.schema.mof +dsc_diskaccesspath | [DiskAccessPath](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/StorageDsc/DSCResources/MSFT_DiskAccessPath) | import/dsc_resources/StorageDsc/DSCResources/MSFT_DiskAccessPath/MSFT_DiskAccessPath.schema.mof +dsc_mountimage | [MountImage](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/StorageDsc/DSCResources/MSFT_MountImage) | import/dsc_resources/StorageDsc/DSCResources/MSFT_MountImage/MSFT_MountImage.schema.mof +dsc_opticaldiskdriveletter | [OpticalDiskDriveLetter](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/StorageDsc/DSCResources/MSFT_OpticalDiskDriveLetter) | import/dsc_resources/StorageDsc/DSCResources/MSFT_OpticalDiskDriveLetter/MSFT_OpticalDiskDriveLetter.schema.mof +dsc_waitfordisk | [WaitForDisk](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/StorageDsc/DSCResources/MSFT_WaitForDisk) | import/dsc_resources/StorageDsc/DSCResources/MSFT_WaitForDisk/MSFT_WaitForDisk.schema.mof +dsc_waitforvolume | [WaitForVolume](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/StorageDsc/DSCResources/MSFT_WaitForVolume) | import/dsc_resources/StorageDsc/DSCResources/MSFT_WaitForVolume/MSFT_WaitForVolume.schema.mof dsc_systemlocale | [SystemLocale](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/SystemLocaleDsc/DSCResources/MSFT_SystemLocale) | import/dsc_resources/SystemLocaleDsc/DSCResources/MSFT_SystemLocale/MSFT_SystemLocale.schema.mof dsc_runbookdirectory | [RunbookDirectory](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/xSCSMA/DSCResources/MSFT_xRunbookDirectory) | import/dsc_resources/xSCSMA/DSCResources/MSFT_xRunbookDirectory/MSFT_xRunbookDirectory.schema.mof dsc_smavariable | [SmaVariable](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/xSCSMA/DSCResources/MSFT_xSmaVariable) | import/dsc_resources/xSCSMA/DSCResources/MSFT_xSmaVariable/MSFT_xSmaVariable.schema.mof @@ -483,41 +519,6 @@ dsc_xscvmmconsoleupdate | [xSCVMMConsoleUpdate](https://github.com/puppetlabs/pu dsc_xscvmmmanagementserversetup | [xSCVMMManagementServerSetup](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xSCVMM/DSCResources/MSFT_xSCVMMManagementServerSetup) | [repo](https://github.com/PowerShell/xSCVMM) dsc_xscvmmmanagementserverupdate | [xSCVMMManagementServerUpdate](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xSCVMM/DSCResources/MSFT_xSCVMMManagementServerUpdate) | [repo](https://github.com/PowerShell/xSCVMM) -##### xSQLServer - -Puppet Type | DSC Resource | Github Repo ------------ | ----------------- | ----- -dsc_xsqlaogroupensure | [xSQLAOGroupEnsure](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLAOGroupEnsure) | [repo](https://github.com/PowerShell/xSQLServer) -dsc_xsqlaogroupjoin | [xSQLAOGroupJoin](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLAOGroupJoin) | [repo](https://github.com/PowerShell/xSQLServer) -dsc_xsqlserveralias | [xSQLServerAlias](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAlias) | [repo](https://github.com/PowerShell/xSQLServer) -dsc_xsqlserveralwaysonavailabilitygroup | [xSQLServerAlwaysOnAvailabilityGroup](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAlwaysOnAvailabilityGroup) | [repo](https://github.com/PowerShell/xSQLServer) -dsc_xsqlserveralwaysonavailabilitygroupreplica | [xSQLServerAlwaysOnAvailabilityGroupReplica](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAlwaysOnAvailabilityGroupReplica) | [repo](https://github.com/PowerShell/xSQLServer) -dsc_xsqlserveralwaysonservice | [xSQLServerAlwaysOnService](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAlwaysOnService) | [repo](https://github.com/PowerShell/xSQLServer) -dsc_xsqlserveravailabilitygrouplistener | [xSQLServerAvailabilityGroupListener](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAvailabilityGroupListener) | [repo](https://github.com/PowerShell/xSQLServer) -dsc_xsqlserverconfiguration | [xSQLServerConfiguration](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerConfiguration) | [repo](https://github.com/PowerShell/xSQLServer) -dsc_xsqlserverdatabase | [xSQLServerDatabase](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerDatabase) | [repo](https://github.com/PowerShell/xSQLServer) -dsc_xsqlserverdatabaseowner | [xSQLServerDatabaseOwner](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerDatabaseOwner) | [repo](https://github.com/PowerShell/xSQLServer) -dsc_xsqlserverdatabasepermission | [xSQLServerDatabasePermission](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerDatabasePermission) | [repo](https://github.com/PowerShell/xSQLServer) -dsc_xsqlserverdatabaserecoverymodel | [xSQLServerDatabaseRecoveryModel](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerDatabaseRecoveryModel) | [repo](https://github.com/PowerShell/xSQLServer) -dsc_xsqlserverdatabaserole | [xSQLServerDatabaseRole](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerDatabaseRole) | [repo](https://github.com/PowerShell/xSQLServer) -dsc_xsqlserverendpoint | [xSQLServerEndpoint](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerEndpoint) | [repo](https://github.com/PowerShell/xSQLServer) -dsc_xsqlserverendpointpermission | [xSQLServerEndpointPermission](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerEndpointPermission) | [repo](https://github.com/PowerShell/xSQLServer) -dsc_xsqlserverendpointstate | [xSQLServerEndpointState](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerEndpointState) | [repo](https://github.com/PowerShell/xSQLServer) -dsc_xsqlserverfailoverclustersetup | [xSQLServerFailoverClusterSetup](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerFailoverClusterSetup) | [repo](https://github.com/PowerShell/xSQLServer) -dsc_xsqlserverfirewall | [xSQLServerFirewall](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerFirewall) | [repo](https://github.com/PowerShell/xSQLServer) -dsc_xsqlserverlogin | [xSQLServerLogin](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerLogin) | [repo](https://github.com/PowerShell/xSQLServer) -dsc_xsqlservermaxdop | [xSQLServerMaxDop](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerMaxDop) | [repo](https://github.com/PowerShell/xSQLServer) -dsc_xsqlservermemory | [xSQLServerMemory](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerMemory) | [repo](https://github.com/PowerShell/xSQLServer) -dsc_xsqlservernetwork | [xSQLServerNetwork](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerNetwork) | [repo](https://github.com/PowerShell/xSQLServer) -dsc_xsqlserverpermission | [xSQLServerPermission](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerPermission) | [repo](https://github.com/PowerShell/xSQLServer) -dsc_xsqlserverrsconfig | [xSQLServerRSConfig](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerRSConfig) | [repo](https://github.com/PowerShell/xSQLServer) -dsc_xsqlserverrssecureconnectionlevel | [xSQLServerRSSecureConnectionLevel](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerRSSecureConnectionLevel) | [repo](https://github.com/PowerShell/xSQLServer) -dsc_xsqlserverreplication | [xSQLServerReplication](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerReplication) | [repo](https://github.com/PowerShell/xSQLServer) -dsc_xsqlserverrole | [xSQLServerRole](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerRole) | [repo](https://github.com/PowerShell/xSQLServer) -dsc_xsqlserverscript | [xSQLServerScript](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerScript) | [repo](https://github.com/PowerShell/xSQLServer) -dsc_xsqlserversetup | [xSQLServerSetup](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerSetup) | [repo](https://github.com/PowerShell/xSQLServer) -dsc_xwaitforavailabilitygroup | [xWaitForAvailabilityGroup](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xWaitForAvailabilityGroup) | [repo](https://github.com/PowerShell/xSQLServer) - ##### xSmbShare Puppet Type | DSC Resource | Github Repo @@ -535,16 +536,6 @@ dsc_xsqlhaservice | [xSqlHAService](https://github.com/puppetlabs/puppetlabs-dsc dsc_xsqlserverinstall | [xSqlServerInstall](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xSqlPs/DSCResources/MSFT_xSqlServerInstall) | [repo](https://github.com/PowerShell/xSqlPs) dsc_xwaitforsqlhagroup | [xWaitForSqlHAGroup](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xSqlPs/DSCResources/MSFT_xWaitForSqlHAGroup) | [repo](https://github.com/PowerShell/xSqlPs) -##### xStorage - -Puppet Type | DSC Resource | Github Repo ------------ | ----------------- | ----- -dsc_xdisk | [xDisk](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xDisk) | [repo](https://github.com/PowerShell/xStorage) -dsc_xdiskaccesspath | [xDiskAccessPath](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xDiskAccessPath) | [repo](https://github.com/PowerShell/xStorage) -dsc_xmountimage | [xMountImage](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xMountImage) | [repo](https://github.com/PowerShell/xStorage) -dsc_xwaitfordisk | [xWaitForDisk](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xWaitForDisk) | [repo](https://github.com/PowerShell/xStorage) -dsc_xwaitforvolume | [xWaitForVolume](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/lib/puppet_x/dsc_resources/xStorage/DSCResources/MSFT_xWaitForVolume) | [repo](https://github.com/PowerShell/xStorage) - ##### xTimeZone Puppet Type | DSC Resource | Github Repo From 6682ba042a34c6c8ea5bb0447791e91007a0726f Mon Sep 17 00:00:00 2001 From: James Pogran Date: Fri, 9 Feb 2018 14:58:38 -0500 Subject: [PATCH 05/25] (MODULES-6592) Update SqlServerDsc to 11.0.0.0 This commit updates SqlServerDsc to the latest gallery versions. Note: This is a BREAKING change. In commit https://github.com/PowerShell/SqlServerDsc/commit/afca9290e6281bd27eca54de236a2d378ea5798b the xSQLServer DSC Resource was renamed from xSQLServer to SqlServerDsc (everything from repo name to PS module) and then all files and folder names were shortened (i.e. xSQLServerSetup to 'SqlSetup', etc). In commit https://github.com/PowerShell/DscResources/commit/20b9f0000d4c7d10499efb13bdb27b00dd41211f the xSQLServer git submodule was removed, and the SqlServerDsc submodule was added in https://github.com/PowerShell/DscResources/commit/27bedc3ac8d7f7c760df15f29d69e568530276d8. This means that anyone using xSQLServer has to migrate their manifests to SqlServerDsc when they update to this dsc module release. --- dsc_resource_release_tags.yml | 1 + ...aysonavailabilitygroup.rb => dsc_sqlag.rb} | 145 +- lib/puppet/type/dsc_sqlagdatabase.rb | 236 +++ ...ygrouplistener.rb => dsc_sqlaglistener.rb} | 24 +- ...itygroupreplica.rb => dsc_sqlagreplica.rb} | 100 +- ...dsc_xsqlserveralias.rb => dsc_sqlalias.rb} | 18 +- ...vermaxdop.rb => dsc_sqlalwaysonservice.rb} | 98 +- ...qlserverdatabase.rb => dsc_sqldatabase.rb} | 47 +- ...k.rb => dsc_sqldatabasedefaultlocation.rb} | 109 +- ...tabaseowner.rb => dsc_sqldatabaseowner.rb} | 28 +- ...ission.rb => dsc_sqldatabasepermission.rb} | 40 +- ...del.rb => dsc_sqldatabaserecoverymodel.rb} | 32 +- ...databaserole.rb => dsc_sqldatabaserole.rb} | 32 +- lib/puppet/type/dsc_sqlrs.rb | 213 +++ ...c_xsqlserverscript.rb => dsc_sqlscript.rb} | 38 +- ...ation.rb => dsc_sqlserverconfiguration.rb} | 40 +- ...ensure.rb => dsc_sqlserverdatabasemail.rb} | 191 +-- ...erendpoint.rb => dsc_sqlserverendpoint.rb} | 30 +- ....rb => dsc_sqlserverendpointpermission.rb} | 22 +- ...state.rb => dsc_sqlserverendpointstate.rb} | 22 +- ...qlserverlogin.rb => dsc_sqlserverlogin.rb} | 48 +- lib/puppet/type/dsc_sqlservermaxdop.rb | 186 +++ ...servermemory.rb => dsc_sqlservermemory.rb} | 62 +- lib/puppet/type/dsc_sqlservernetwork.rb | 199 +++ ...rmission.rb => dsc_sqlserverpermission.rb} | 42 +- ...ication.rb => dsc_sqlserverreplication.rb} | 16 +- ...xsqlserverrole.rb => dsc_sqlserverrole.rb} | 32 +- lib/puppet/type/dsc_sqlserviceaccount.rb | 185 +++ ...dsc_xsqlserversetup.rb => dsc_sqlsetup.rb} | 70 +- ...ailabilitygroup.rb => dsc_sqlwaitforag.rb} | 38 +- ...rfirewall.rb => dsc_sqlwindowsfirewall.rb} | 16 +- lib/puppet/type/dsc_xsqlaogroupjoin.rb | 153 -- .../type/dsc_xsqlserveralwaysonservice.rb | 140 -- .../dsc_xsqlserverfailoverclustersetup.rb | 795 --------- lib/puppet/type/dsc_xsqlserverrsconfig.rb | 147 -- .../dsc_xsqlserverrssecureconnectionlevel.rb | 121 -- .../DSCResources/CommonResourceHelper.psm1 | 265 +++ .../DSCResources/MSFT_SqlAG/MSFT_SqlAG.psm1} | 565 +++---- .../MSFT_SqlAG/MSFT_SqlAG.schema.mof} | 15 +- .../MSFT_SqlAGDatabase.psm1 | 986 ++++++++++++ .../MSFT_SqlAGDatabase.schema.mof | 14 + .../en-US/MSFT_SqlAGDatabase.strings.psd1 | 15 + .../MSFT_SqlAGListener.psm1} | 100 +- .../MSFT_SqlAGListener.schema.mof} | 8 +- .../MSFT_SqlAGReplica/MSFT_SqlAGReplica.psm1} | 428 +++-- .../MSFT_SqlAGReplica.schema.mof} | 21 +- .../MSFT_SqlAlias/MSFT_SqlAlias.psm1} | 34 +- .../MSFT_SqlAlias/MSFT_SqlAlias.schema.mof} | 6 +- .../MSFT_SqlAlwaysOnService.psm1 | 208 +++ .../MSFT_SqlAlwaysOnService.schema.mof | 9 + .../MSFT_SqlDatabase/MSFT_SqlDatabase.psm1} | 170 +- .../MSFT_SqlDatabase.schema.mof} | 9 +- .../MSFT_SqlDatabaseDefaultLocation.psm1 | 292 ++++ ...MSFT_SqlDatabaseDefaultLocation.schema.mof | 11 + ...FT_SqlDatabaseDefaultLocation.strings.psd1 | 13 + .../MSFT_SqlDatabaseOwner.psm1} | 68 +- .../MSFT_SqlDatabaseOwner.schema.mof} | 8 +- .../MSFT_SqlDatabasePermission.psm1 | 410 +++++ .../MSFT_SqlDatabasePermission.schema.mof} | 10 +- .../MSFT_SqlDatabaseRecoveryModel.psm1} | 68 +- .../MSFT_SqlDatabaseRecoveryModel.schema.mof} | 8 +- .../MSFT_SqlDatabaseRole.psm1} | 154 +- .../MSFT_SqlDatabaseRole.schema.mof} | 8 +- .../DSCResources/MSFT_SqlRS/MSFT_SqlRS.psm1 | 926 +++++++++++ .../MSFT_SqlRS/MSFT_SqlRS.schema.mof | 13 + .../MSFT_SqlScript/MSFT_SqlScript.psm1} | 91 +- .../MSFT_SqlScript/MSFT_SqlScript.schema.mof} | 9 +- .../MSFT_SqlServerConfiguration.psm1 | 267 +++ .../MSFT_SqlServerConfiguration.schema.mof} | 12 +- .../MSFT_SqlServerConfiguration.strings.psd1 | 12 + .../MSFT_SqlServerDatabaseMail.psm1 | 732 +++++++++ .../MSFT_SqlServerDatabaseMail.schema.mof | 16 + .../MSFT_SqlServerDatabaseMail.strings.psd1 | 33 + .../MSFT_SqlServerEndpoint.psm1} | 70 +- .../MSFT_SqlServerEndpoint.schema.mof} | 8 +- .../MSFT_SqlServerEndpointPermission.psm1} | 50 +- ...FT_SqlServerEndpointPermission.schema.mof} | 6 +- .../MSFT_SqlServerEndpointState.psm1} | 42 +- .../MSFT_SqlServerEndpointState.schema.mof} | 6 +- .../MSFT_SqlServerLogin.psm1} | 204 ++- .../MSFT_SqlServerLogin.schema.mof} | 9 +- .../MSFT_SqlServerMaxDop.psm1} | 135 +- .../MSFT_SqlServerMaxDop.schema.mof | 11 + .../MSFT_SqlServerMemory.psm1} | 176 +- .../MSFT_SqlServerMemory.schema.mof} | 14 +- .../MSFT_SqlServerNetwork.psm1 | 383 +++++ .../MSFT_SqlServerNetwork.schema.mof | 12 + .../en-US/MSFT_SqlServerNetwork.strings.psd1 | 12 + .../MSFT_SqlServerPermission.psm1 | 357 +++++ .../MSFT_SqlServerPermission.schema.mof | 9 + .../MSFT_SqlServerReplication.psm1} | 149 +- .../MSFT_SqlServerReplication.schema.mof} | 4 +- .../MSFT_SqlServerRole.psm1} | 262 +-- .../MSFT_SqlServerRole.schema.mof} | 8 +- .../en-US/MSFT_SqlServerRole.strings.psd1 | 23 + .../MSFT_SqlServiceAccount.psm1 | 442 +++++ .../MSFT_SqlServiceAccount.schema.mof | 11 + .../en-US/MSFT_SqlServiceAccount.strings.psd1 | 13 + .../MSFT_SqlSetup/MSFT_SqlSetup.psm1} | 564 ++++--- .../MSFT_SqlSetup/MSFT_SqlSetup.schema.mof} | 9 +- .../en-US/MSFT_SqlSetup.strings.psd1 | 77 + .../sv-SE/MSFT_SqlSetup.strings.psd1 | 77 + .../MSFT_SqlWaitForAG/MSFT_SqlWaitForAG.psm1 | 175 ++ .../MSFT_SqlWaitForAG.schema.mof | 8 + .../MSFT_SqlWindowsFirewall.psm1} | 244 +-- .../MSFT_SqlWindowsFirewall.schema.mof} | 14 +- .../{xSQLServer => SqlServerDsc}/LICENSE | 4 +- .../SqlServerDsc/SQLServerDsc.psd1 | 233 +++ .../SqlServerDsc/SqlServerDscHelper.psm1 | 1400 ++++++++++++++++ .../en-US/SqlServerDscHelper.strings.psd1 | 148 ++ .../sv-SE/SqlServerDscHelper.strings.psd1 | 144 ++ .../MSFT_xSQLAOGroupEnsure.psm1 | 367 ----- .../MSFT_xSQLAOGroupEnsure.schema.mof | 17 - .../MSFT_xSQLAOGroupJoin.psm1 | 227 --- .../MSFT_xSQLAOGroupJoin.schema.mof | 10 - .../MSFT_xSQLServerAlwaysOnService.psm1 | 186 --- .../MSFT_xSQLServerAlwaysOnService.schema.mof | 8 - .../MSFT_xSQLServerConfiguration.psm1 | 213 --- .../MSFT_xSQLServerDatabasePermission.psm1 | 278 ---- .../MSFT_xSQLServerFailoverClusterSetup.psm1 | 1038 ------------ ..._xSQLServerFailoverClusterSetup.schema.mof | 51 - .../MSFT_xSQLServerMaxDop.schema.mof | 9 - .../MSFT_xSQLServerNetwork.psm1 | 287 ---- .../MSFT_xSQLServerNetwork.schema.mof | 10 - .../MSFT_xSQLServerPermission.psm1 | 252 --- .../MSFT_xSQLServerPermission.schema.mof | 11 - .../MSFT_xSQLServerRSConfig.psm1 | 229 --- .../MSFT_xSQLServerRSConfig.schema.mof | 9 - ...SFT_xSQLServerRSSecureConnectionLevel.psm1 | 114 -- ...QLServerRSSecureConnectionLevel.schema.mof | 7 - .../MSFT_xWaitForAvailabilityGroup.psm1 | 126 -- .../MSFT_xWaitForAvailabilityGroup.schema.mof | 9 - .../xSQLServer/en-US/xPDT.strings.psd1 | 11 - .../xSQLServer/en-US/xSQLServer.strings.psd1 | 114 -- .../dsc_resources/xSQLServer/xPDT.psm1 | 708 -------- .../dsc_resources/xSQLServer/xSQLServer.psd1 | 174 -- .../xSQLServer/xSQLServerHelper.psm1 | 1428 ----------------- 137 files changed, 11719 insertions(+), 9417 deletions(-) rename lib/puppet/type/{dsc_xsqlserveralwaysonavailabilitygroup.rb => dsc_sqlag.rb} (71%) create mode 100644 lib/puppet/type/dsc_sqlagdatabase.rb rename lib/puppet/type/{dsc_xsqlserveravailabilitygrouplistener.rb => dsc_sqlaglistener.rb} (87%) rename lib/puppet/type/{dsc_xsqlserveralwaysonavailabilitygroupreplica.rb => dsc_sqlagreplica.rb} (76%) rename lib/puppet/type/{dsc_xsqlserveralias.rb => dsc_sqlalias.rb} (90%) rename lib/puppet/type/{dsc_xsqlservermaxdop.rb => dsc_sqlalwaysonservice.rb} (64%) rename lib/puppet/type/{dsc_xsqlserverdatabase.rb => dsc_sqldatabase.rb} (72%) rename lib/puppet/type/{dsc_xsqlservernetwork.rb => dsc_sqldatabasedefaultlocation.rb} (59%) rename lib/puppet/type/{dsc_xsqlserverdatabaseowner.rb => dsc_sqldatabaseowner.rb} (79%) rename lib/puppet/type/{dsc_xsqlserverdatabasepermission.rb => dsc_sqldatabasepermission.rb} (80%) rename lib/puppet/type/{dsc_xsqlserverdatabaserecoverymodel.rb => dsc_sqldatabaserecoverymodel.rb} (76%) rename lib/puppet/type/{dsc_xsqlserverdatabaserole.rb => dsc_sqldatabaserole.rb} (82%) create mode 100644 lib/puppet/type/dsc_sqlrs.rb rename lib/puppet/type/{dsc_xsqlserverscript.rb => dsc_sqlscript.rb} (77%) rename lib/puppet/type/{dsc_xsqlserverconfiguration.rb => dsc_sqlserverconfiguration.rb} (77%) rename lib/puppet/type/{dsc_xsqlaogroupensure.rb => dsc_sqlserverdatabasemail.rb} (50%) rename lib/puppet/type/{dsc_xsqlserverendpoint.rb => dsc_sqlserverendpoint.rb} (83%) rename lib/puppet/type/{dsc_xsqlserverendpointpermission.rb => dsc_sqlserverendpointpermission.rb} (86%) rename lib/puppet/type/{dsc_xsqlserverendpointstate.rb => dsc_sqlserverendpointstate.rb} (83%) rename lib/puppet/type/{dsc_xsqlserverlogin.rb => dsc_sqlserverlogin.rb} (83%) create mode 100644 lib/puppet/type/dsc_sqlservermaxdop.rb rename lib/puppet/type/{dsc_xsqlservermemory.rb => dsc_sqlservermemory.rb} (72%) create mode 100644 lib/puppet/type/dsc_sqlservernetwork.rb rename lib/puppet/type/{dsc_xsqlserverpermission.rb => dsc_sqlserverpermission.rb} (68%) rename lib/puppet/type/{dsc_xsqlserverreplication.rb => dsc_sqlserverreplication.rb} (91%) rename lib/puppet/type/{dsc_xsqlserverrole.rb => dsc_sqlserverrole.rb} (85%) create mode 100644 lib/puppet/type/dsc_sqlserviceaccount.rb rename lib/puppet/type/{dsc_xsqlserversetup.rb => dsc_sqlsetup.rb} (92%) rename lib/puppet/type/{dsc_xwaitforavailabilitygroup.rb => dsc_sqlwaitforag.rb} (67%) rename lib/puppet/type/{dsc_xsqlserverfirewall.rb => dsc_sqlwindowsfirewall.rb} (93%) delete mode 100644 lib/puppet/type/dsc_xsqlaogroupjoin.rb delete mode 100644 lib/puppet/type/dsc_xsqlserveralwaysonservice.rb delete mode 100644 lib/puppet/type/dsc_xsqlserverfailoverclustersetup.rb delete mode 100644 lib/puppet/type/dsc_xsqlserverrsconfig.rb delete mode 100644 lib/puppet/type/dsc_xsqlserverrssecureconnectionlevel.rb create mode 100644 lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/CommonResourceHelper.psm1 rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerAlwaysOnAvailabilityGroup/MSFT_xSQLServerAlwaysOnAvailabilityGroup.psm1 => SqlServerDsc/DSCResources/MSFT_SqlAG/MSFT_SqlAG.psm1} (55%) rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerAlwaysOnAvailabilityGroup/MSFT_xSQLServerAlwaysOnAvailabilityGroup.schema.mof => SqlServerDsc/DSCResources/MSFT_SqlAG/MSFT_SqlAG.schema.mof} (67%) create mode 100644 lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAGDatabase/MSFT_SqlAGDatabase.psm1 create mode 100644 lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAGDatabase/MSFT_SqlAGDatabase.schema.mof create mode 100644 lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAGDatabase/en-US/MSFT_SqlAGDatabase.strings.psd1 rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerAvailabilityGroupListener/MSFT_xSQLServerAvailabilityGroupListener.psm1 => SqlServerDsc/DSCResources/MSFT_SqlAGListener/MSFT_SqlAGListener.psm1} (84%) rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerAvailabilityGroupListener/MSFT_xSQLServerAvailabilityGroupListener.schema.mof => SqlServerDsc/DSCResources/MSFT_SqlAGListener/MSFT_SqlAGListener.schema.mof} (82%) rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerAlwaysOnAvailabilityGroupReplica/MSFT_xSQLServerAlwaysOnAvailabilityGroupReplica.psm1 => SqlServerDsc/DSCResources/MSFT_SqlAGReplica/MSFT_SqlAGReplica.psm1} (69%) rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerAlwaysOnAvailabilityGroupReplica/MSFT_xSQLServerAlwaysOnAvailabilityGroupReplica.schema.mof => SqlServerDsc/DSCResources/MSFT_SqlAGReplica/MSFT_SqlAGReplica.schema.mof} (73%) rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerAlias/MSFT_xSQLServerAlias.psm1 => SqlServerDsc/DSCResources/MSFT_SqlAlias/MSFT_SqlAlias.psm1} (95%) rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerAlias/MSFT_xSQLServerAlias.schema.mof => SqlServerDsc/DSCResources/MSFT_SqlAlias/MSFT_SqlAlias.schema.mof} (81%) create mode 100644 lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAlwaysOnService/MSFT_SqlAlwaysOnService.psm1 create mode 100644 lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAlwaysOnService/MSFT_SqlAlwaysOnService.schema.mof rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerDatabase/MSFT_xSQLServerDatabase.psm1 => SqlServerDsc/DSCResources/MSFT_SqlDatabase/MSFT_SqlDatabase.psm1} (53%) rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerDatabase/MSFT_xSQLServerDatabase.schema.mof => SqlServerDsc/DSCResources/MSFT_SqlDatabase/MSFT_SqlDatabase.schema.mof} (61%) create mode 100644 lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseDefaultLocation/MSFT_SqlDatabaseDefaultLocation.psm1 create mode 100644 lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseDefaultLocation/MSFT_SqlDatabaseDefaultLocation.schema.mof create mode 100644 lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseDefaultLocation/en-US/MSFT_SqlDatabaseDefaultLocation.strings.psd1 rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerDatabaseOwner/MSFT_xSQLServerDatabaseOwner.psm1 => SqlServerDsc/DSCResources/MSFT_SqlDatabaseOwner/MSFT_SqlDatabaseOwner.psm1} (70%) rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerDatabaseOwner/MSFT_xSQLServerDatabaseOwner.schema.mof => SqlServerDsc/DSCResources/MSFT_SqlDatabaseOwner/MSFT_SqlDatabaseOwner.schema.mof} (64%) create mode 100644 lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabasePermission/MSFT_SqlDatabasePermission.psm1 rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerDatabasePermission/MSFT_xSQLServerDatabasePermission.schema.mof => SqlServerDsc/DSCResources/MSFT_SqlDatabasePermission/MSFT_SqlDatabasePermission.schema.mof} (67%) rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerDatabaseRecoveryModel/MSFT_xSQLServerDatabaseRecoveryModel.psm1 => SqlServerDsc/DSCResources/MSFT_SqlDatabaseRecoveryModel/MSFT_SqlDatabaseRecoveryModel.psm1} (73%) rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerDatabaseRecoveryModel/MSFT_xSQLServerDatabaseRecoveryModel.schema.mof => SqlServerDsc/DSCResources/MSFT_SqlDatabaseRecoveryModel/MSFT_SqlDatabaseRecoveryModel.schema.mof} (65%) rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerDatabaseRole/MSFT_xSQLServerDatabaseRole.psm1 => SqlServerDsc/DSCResources/MSFT_SqlDatabaseRole/MSFT_SqlDatabaseRole.psm1} (71%) rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerDatabaseRole/MSFT_xSQLServerDatabaseRole.schema.mof => SqlServerDsc/DSCResources/MSFT_SqlDatabaseRole/MSFT_SqlDatabaseRole.schema.mof} (80%) create mode 100644 lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlRS/MSFT_SqlRS.psm1 create mode 100644 lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlRS/MSFT_SqlRS.schema.mof rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerScript/MSFT_xSQLServerScript.psm1 => SqlServerDsc/DSCResources/MSFT_SqlScript/MSFT_SqlScript.psm1} (69%) rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerScript/MSFT_xSQLServerScript.Schema.mof => SqlServerDsc/DSCResources/MSFT_SqlScript/MSFT_SqlScript.schema.mof} (61%) create mode 100644 lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerConfiguration/MSFT_SqlServerConfiguration.psm1 rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerConfiguration/MSFT_xSQLServerConfiguration.schema.mof => SqlServerDsc/DSCResources/MSFT_SqlServerConfiguration/MSFT_SqlServerConfiguration.schema.mof} (65%) create mode 100644 lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerConfiguration/en-US/MSFT_SqlServerConfiguration.strings.psd1 create mode 100644 lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerDatabaseMail/MSFT_SqlServerDatabaseMail.psm1 create mode 100644 lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerDatabaseMail/MSFT_SqlServerDatabaseMail.schema.mof create mode 100644 lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerDatabaseMail/en-US/MSFT_SqlServerDatabaseMail.strings.psd1 rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerEndpoint/MSFT_xSQLServerEndpoint.psm1 => SqlServerDsc/DSCResources/MSFT_SqlServerEndpoint/MSFT_SqlServerEndpoint.psm1} (82%) rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerEndpoint/MSFT_xSQLServerEndpoint.schema.mof => SqlServerDsc/DSCResources/MSFT_SqlServerEndpoint/MSFT_SqlServerEndpoint.schema.mof} (75%) rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerEndpointPermission/MSFT_xSQLServerEndpointPermission.psm1 => SqlServerDsc/DSCResources/MSFT_SqlServerEndpointPermission/MSFT_SqlServerEndpointPermission.psm1} (83%) rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerEndpointPermission/MSFT_xSQLServerEndpointPermission.schema.mof => SqlServerDsc/DSCResources/MSFT_SqlServerEndpointPermission/MSFT_SqlServerEndpointPermission.schema.mof} (80%) rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerEndpointState/MSFT_xSQLServerEndpointState.psm1 => SqlServerDsc/DSCResources/MSFT_SqlServerEndpointState/MSFT_SqlServerEndpointState.psm1} (80%) rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerEndpointState/MSFT_xSQLServerEndpointState.schema.mof => SqlServerDsc/DSCResources/MSFT_SqlServerEndpointState/MSFT_SqlServerEndpointState.schema.mof} (70%) rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerLogin/MSFT_xSQLServerLogin.psm1 => SqlServerDsc/DSCResources/MSFT_SqlServerLogin/MSFT_SqlServerLogin.psm1} (77%) rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerLogin/MSFT_xSQLServerLogin.schema.mof => SqlServerDsc/DSCResources/MSFT_SqlServerLogin/MSFT_SqlServerLogin.schema.mof} (86%) rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerMaxDop/MSFT_xSQLServerMaxDop.psm1 => SqlServerDsc/DSCResources/MSFT_SqlServerMaxDop/MSFT_SqlServerMaxDop.psm1} (64%) create mode 100644 lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerMaxDop/MSFT_SqlServerMaxDop.schema.mof rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerMemory/MSFT_xSQLServerMemory.psm1 => SqlServerDsc/DSCResources/MSFT_SqlServerMemory/MSFT_SqlServerMemory.psm1} (59%) rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerMemory/MSFT_xSQLServerMemory.schema.mof => SqlServerDsc/DSCResources/MSFT_SqlServerMemory/MSFT_SqlServerMemory.schema.mof} (58%) create mode 100644 lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerNetwork/MSFT_SqlServerNetwork.psm1 create mode 100644 lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerNetwork/MSFT_SqlServerNetwork.schema.mof create mode 100644 lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerNetwork/en-US/MSFT_SqlServerNetwork.strings.psd1 create mode 100644 lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerPermission/MSFT_SqlServerPermission.psm1 create mode 100644 lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerPermission/MSFT_SqlServerPermission.schema.mof rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerReplication/MSFT_xSQLServerReplication.psm1 => SqlServerDsc/DSCResources/MSFT_SqlServerReplication/MSFT_SqlServerReplication.psm1} (78%) rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerReplication/MSFT_xSQLServerReplication.schema.mof => SqlServerDsc/DSCResources/MSFT_SqlServerReplication/MSFT_SqlServerReplication.schema.mof} (88%) rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerRole/MSFT_xSQLServerRole.psm1 => SqlServerDsc/DSCResources/MSFT_SqlServerRole/MSFT_SqlServerRole.psm1} (61%) rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerRole/MSFT_xSQLServerRole.schema.mof => SqlServerDsc/DSCResources/MSFT_SqlServerRole/MSFT_SqlServerRole.schema.mof} (86%) create mode 100644 lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerRole/en-US/MSFT_SqlServerRole.strings.psd1 create mode 100644 lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServiceAccount/MSFT_SqlServiceAccount.psm1 create mode 100644 lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServiceAccount/MSFT_SqlServiceAccount.schema.mof create mode 100644 lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServiceAccount/en-US/MSFT_SqlServiceAccount.strings.psd1 rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerSetup/MSFT_xSQLServerSetup.psm1 => SqlServerDsc/DSCResources/MSFT_SqlSetup/MSFT_SqlSetup.psm1} (75%) rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerSetup/MSFT_xSQLServerSetup.schema.mof => SqlServerDsc/DSCResources/MSFT_SqlSetup/MSFT_SqlSetup.schema.mof} (86%) create mode 100644 lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlSetup/en-US/MSFT_SqlSetup.strings.psd1 create mode 100644 lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlSetup/sv-SE/MSFT_SqlSetup.strings.psd1 create mode 100644 lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlWaitForAG/MSFT_SqlWaitForAG.psm1 create mode 100644 lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlWaitForAG/MSFT_SqlWaitForAG.schema.mof rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerFirewall/MSFT_xSQLServerFirewall.psm1 => SqlServerDsc/DSCResources/MSFT_SqlWindowsFirewall/MSFT_SqlWindowsFirewall.psm1} (77%) rename lib/puppet_x/dsc_resources/{xSQLServer/DSCResources/MSFT_xSQLServerFirewall/MSFT_xSQLServerFirewall.schema.mof => SqlServerDsc/DSCResources/MSFT_SqlWindowsFirewall/MSFT_SqlWindowsFirewall.schema.mof} (74%) rename lib/puppet_x/dsc_resources/{xSQLServer => SqlServerDsc}/LICENSE (94%) create mode 100644 lib/puppet_x/dsc_resources/SqlServerDsc/SQLServerDsc.psd1 create mode 100644 lib/puppet_x/dsc_resources/SqlServerDsc/SqlServerDscHelper.psm1 create mode 100644 lib/puppet_x/dsc_resources/SqlServerDsc/en-US/SqlServerDscHelper.strings.psd1 create mode 100644 lib/puppet_x/dsc_resources/SqlServerDsc/sv-SE/SqlServerDscHelper.strings.psd1 delete mode 100644 lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLAOGroupEnsure/MSFT_xSQLAOGroupEnsure.psm1 delete mode 100644 lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLAOGroupEnsure/MSFT_xSQLAOGroupEnsure.schema.mof delete mode 100644 lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLAOGroupJoin/MSFT_xSQLAOGroupJoin.psm1 delete mode 100644 lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLAOGroupJoin/MSFT_xSQLAOGroupJoin.schema.mof delete mode 100644 lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAlwaysOnService/MSFT_xSQLServerAlwaysOnService.psm1 delete mode 100644 lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAlwaysOnService/MSFT_xSQLServerAlwaysOnService.schema.mof delete mode 100644 lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerConfiguration/MSFT_xSQLServerConfiguration.psm1 delete mode 100644 lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerDatabasePermission/MSFT_xSQLServerDatabasePermission.psm1 delete mode 100644 lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerFailoverClusterSetup/MSFT_xSQLServerFailoverClusterSetup.psm1 delete mode 100644 lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerFailoverClusterSetup/MSFT_xSQLServerFailoverClusterSetup.schema.mof delete mode 100644 lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerMaxDop/MSFT_xSQLServerMaxDop.schema.mof delete mode 100644 lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerNetwork/MSFT_xSQLServerNetwork.psm1 delete mode 100644 lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerNetwork/MSFT_xSQLServerNetwork.schema.mof delete mode 100644 lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerPermission/MSFT_xSQLServerPermission.psm1 delete mode 100644 lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerPermission/MSFT_xSQLServerPermission.schema.mof delete mode 100644 lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerRSConfig/MSFT_xSQLServerRSConfig.psm1 delete mode 100644 lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerRSConfig/MSFT_xSQLServerRSConfig.schema.mof delete mode 100644 lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerRSSecureConnectionLevel/MSFT_xSQLServerRSSecureConnectionLevel.psm1 delete mode 100644 lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerRSSecureConnectionLevel/MSFT_xSQLServerRSSecureConnectionLevel.schema.mof delete mode 100644 lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xWaitForAvailabilityGroup/MSFT_xWaitForAvailabilityGroup.psm1 delete mode 100644 lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xWaitForAvailabilityGroup/MSFT_xWaitForAvailabilityGroup.schema.mof delete mode 100644 lib/puppet_x/dsc_resources/xSQLServer/en-US/xPDT.strings.psd1 delete mode 100644 lib/puppet_x/dsc_resources/xSQLServer/en-US/xSQLServer.strings.psd1 delete mode 100644 lib/puppet_x/dsc_resources/xSQLServer/xPDT.psm1 delete mode 100644 lib/puppet_x/dsc_resources/xSQLServer/xSQLServer.psd1 delete mode 100644 lib/puppet_x/dsc_resources/xSQLServer/xSQLServerHelper.psm1 diff --git a/dsc_resource_release_tags.yml b/dsc_resource_release_tags.yml index 5025cae83..033fffbc8 100644 --- a/dsc_resource_release_tags.yml +++ b/dsc_resource_release_tags.yml @@ -3,6 +3,7 @@ AuditPolicyDsc: 1.1.0.0-PSGallery OfficeOnlineServerDsc: 1.0.0.0-PSGallery SecurityPolicyDsc: 1.5.0.0-PSGallery SharePointDsc: 1.8.0.0-PSGallery +SqlServerDsc: 11.0.0.0-PSGallery StorageDsc: 4.0.0.0-PSGallery SystemLocaleDsc: 1.1.0.0-PSGallery xActiveDirectory: 2.16.0.0-PSGallery diff --git a/lib/puppet/type/dsc_xsqlserveralwaysonavailabilitygroup.rb b/lib/puppet/type/dsc_sqlag.rb similarity index 71% rename from lib/puppet/type/dsc_xsqlserveralwaysonavailabilitygroup.rb rename to lib/puppet/type/dsc_sqlag.rb index 089ca85c1..105984954 100644 --- a/lib/puppet/type/dsc_xsqlserveralwaysonavailabilitygroup.rb +++ b/lib/puppet/type/dsc_sqlag.rb @@ -1,14 +1,14 @@ require 'pathname' -Puppet::Type.newtype(:dsc_xsqlserveralwaysonavailabilitygroup) do +Puppet::Type.newtype(:dsc_sqlag) do require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' @doc = %q{ - The DSC xSQLServerAlwaysOnAvailabilityGroup resource type. + The DSC SqlAG resource type. Automatically generated from - 'xSQLServer/DSCResources/MSFT_xSQLServerAlwaysOnAvailabilityGroup/MSFT_xSQLServerAlwaysOnAvailabilityGroup.schema.mof' + 'SqlServerDsc/DSCResources/MSFT_SqlAG/MSFT_SqlAG.schema.mof' To learn more about PowerShell Desired State Configuration, please visit https://technet.microsoft.com/en-us/library/dn249912.aspx. @@ -22,13 +22,13 @@ validate do fail('dsc_name is a required attribute') if self[:dsc_name].nil? - fail('dsc_sqlinstancename is a required attribute') if self[:dsc_sqlinstancename].nil? + fail('dsc_instancename is a required attribute') if self[:dsc_instancename].nil? end - def dscmeta_resource_friendly_name; 'xSQLServerAlwaysOnAvailabilityGroup' end - def dscmeta_resource_name; 'MSFT_xSQLServerAlwaysOnAvailabilityGroup' end - def dscmeta_module_name; 'xSQLServer' end - def dscmeta_module_version; '7.0.0.0' end + def dscmeta_resource_friendly_name; 'SqlAG' end + def dscmeta_resource_name; 'MSFT_SqlAG' end + def dscmeta_module_name; 'SqlServerDsc' end + def dscmeta_module_version; '11.0.0.0' end newparam(:name, :namevar => true ) do end @@ -72,14 +72,14 @@ def mof_is_embedded?; false end end end - # Name: SQLServer + # Name: ServerName # Type: string # IsMandatory: False # Values: None - newparam(:dsc_sqlserver) do + newparam(:dsc_servername) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "SQLServer - Hostname of the SQL Server to be configured." + desc "ServerName - Hostname of the SQL Server to be configured." validate do |value| unless value.kind_of?(String) fail("Invalid value '#{value}'. Should be a string") @@ -87,14 +87,14 @@ def mof_is_embedded?; false end end end - # Name: SQLInstanceName + # Name: InstanceName # Type: string # IsMandatory: True # Values: None - newparam(:dsc_sqlinstancename) do + newparam(:dsc_instancename) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "SQLInstanceName - Name of the SQL instance to be configued." + desc "InstanceName - Name of the SQL instance to be configured." isrequired validate do |value| unless value.kind_of?(String) @@ -192,6 +192,38 @@ def mof_is_embedded?; false end end end + # Name: DatabaseHealthTrigger + # Type: boolean + # IsMandatory: False + # Values: None + newparam(:dsc_databasehealthtrigger) do + def mof_type; 'boolean' end + def mof_is_embedded?; false end + desc "DatabaseHealthTrigger - Specifies if the option Database Level Health Detection is enabled. This is only available is SQL Server 2016 and later and is ignored when applied to previous versions." + validate do |value| + end + newvalues(true, false) + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_boolean(value.to_s) + end + end + + # Name: DtcSupportEnabled + # Type: boolean + # IsMandatory: False + # Values: None + newparam(:dsc_dtcsupportenabled) do + def mof_type; 'boolean' end + def mof_is_embedded?; false end + desc "DtcSupportEnabled - Specifies if the option Database DTC Support is enabled. This is only available is SQL Server 2016 and later and is ignored when applied to previous versions. This can't be altered once the Availability Group is created and is ignored if it is the case." + validate do |value| + end + newvalues(true, false) + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_boolean(value.to_s) + end + end + # Name: ConnectionModeInPrimaryRole # Type: string # IsMandatory: False @@ -297,6 +329,89 @@ def mof_is_embedded?; false end end end + # Name: ProcessOnlyOnActiveNode + # Type: boolean + # IsMandatory: False + # Values: None + newparam(:dsc_processonlyonactivenode) do + def mof_type; 'boolean' end + def mof_is_embedded?; false end + desc "ProcessOnlyOnActiveNode - Specifies that the resource will only determine if a change is needed if the target node is the active host of the SQL Server Instance." + validate do |value| + end + newvalues(true, false) + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_boolean(value.to_s) + end + end + + # Name: EndpointUrl + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_endpointurl) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "EndpointUrl - Gets the Endpoint URL of the availability group replica endpoint." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: EndpointPort + # Type: uint32 + # IsMandatory: False + # Values: None + newparam(:dsc_endpointport) do + def mof_type; 'uint32' end + def mof_is_embedded?; false end + desc "EndpointPort - Gets the port the database mirroring endpoint is listening on." + validate do |value| + unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) + fail("Invalid value #{value}. Should be a unsigned Integer") + end + end + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_integer(value) + end + end + + # Name: Version + # Type: uint32 + # IsMandatory: False + # Values: None + newparam(:dsc_version) do + def mof_type; 'uint32' end + def mof_is_embedded?; false end + desc "Version - Gets the major version of the SQL Server instance." + validate do |value| + unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) + fail("Invalid value #{value}. Should be a unsigned Integer") + end + end + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_integer(value) + end + end + + # Name: IsActiveNode + # Type: boolean + # IsMandatory: False + # Values: None + newparam(:dsc_isactivenode) do + def mof_type; 'boolean' end + def mof_is_embedded?; false end + desc "IsActiveNode - Determines if the current node is actively hosting the SQL Server instance." + validate do |value| + end + newvalues(true, false) + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_boolean(value.to_s) + end + end + def builddepends pending_relations = super() @@ -304,7 +419,7 @@ def builddepends end end -Puppet::Type.type(:dsc_xsqlserveralwaysonavailabilitygroup).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do +Puppet::Type.type(:dsc_sqlag).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) defaultfor :operatingsystem => :windows diff --git a/lib/puppet/type/dsc_sqlagdatabase.rb b/lib/puppet/type/dsc_sqlagdatabase.rb new file mode 100644 index 000000000..6d018727e --- /dev/null +++ b/lib/puppet/type/dsc_sqlagdatabase.rb @@ -0,0 +1,236 @@ +require 'pathname' + +Puppet::Type.newtype(:dsc_sqlagdatabase) do + require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' + require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' + + + @doc = %q{ + The DSC SqlAGDatabase resource type. + Automatically generated from + 'SqlServerDsc/DSCResources/MSFT_SqlAGDatabase/MSFT_SqlAGDatabase.schema.mof' + + To learn more about PowerShell Desired State Configuration, please + visit https://technet.microsoft.com/en-us/library/dn249912.aspx. + + For more information about built-in DSC Resources, please visit + https://technet.microsoft.com/en-us/library/dn249921.aspx. + + For more information about xDsc Resources, please visit + https://github.com/PowerShell/DscResources. + } + + validate do + fail('dsc_servername is a required attribute') if self[:dsc_servername].nil? + fail('dsc_instancename is a required attribute') if self[:dsc_instancename].nil? + fail('dsc_availabilitygroupname is a required attribute') if self[:dsc_availabilitygroupname].nil? + end + + def dscmeta_resource_friendly_name; 'SqlAGDatabase' end + def dscmeta_resource_name; 'MSFT_SqlAGDatabase' end + def dscmeta_module_name; 'SqlServerDsc' end + def dscmeta_module_version; '11.0.0.0' end + + newparam(:name, :namevar => true ) do + end + + ensurable do + newvalue(:exists?) { provider.exists? } + newvalue(:present) { provider.create } + newvalue(:absent) { provider.destroy } + defaultto { :present } + end + + # Name: PsDscRunAsCredential + # Type: MSFT_Credential + # IsMandatory: False + # Values: None + newparam(:dsc_psdscrunascredential) do + def mof_type; 'MSFT_Credential' end + def mof_is_embedded?; true end + desc "PsDscRunAsCredential" + validate do |value| + unless value.kind_of?(Hash) + fail("Invalid value '#{value}'. Should be a hash") + end + PuppetX::Dsc::TypeHelpers.validate_MSFT_Credential("Credential", value) + end + end + + # Name: DatabaseName + # Type: string[] + # IsMandatory: False + # Values: None + newparam(:dsc_databasename, :array_matching => :all) do + def mof_type; 'string[]' end + def mof_is_embedded?; false end + desc "DatabaseName - The name of the database(s) to add to the availability group. This accepts wildcards." + validate do |value| + unless value.kind_of?(Array) || value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string or an array of strings") + end + end + munge do |value| + Array(value) + end + end + + # Name: ServerName + # Type: string + # IsMandatory: True + # Values: None + newparam(:dsc_servername) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "ServerName - Hostname of the SQL Server where the primary replica of the availability group lives. If the availability group is not currently on this server, the resource will attempt to connect to the server where the primary replica lives." + isrequired + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: InstanceName + # Type: string + # IsMandatory: True + # Values: None + newparam(:dsc_instancename) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "InstanceName - Name of the SQL instance to be configured." + isrequired + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: AvailabilityGroupName + # Type: string + # IsMandatory: True + # Values: None + newparam(:dsc_availabilitygroupname) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "AvailabilityGroupName - The name of the availability group in which to manage the database membership(s)." + isrequired + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: BackupPath + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_backuppath) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "BackupPath - The path used to seed the availability group replicas. This should be a path that is accessible by all of the replicas" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Ensure + # Type: string + # IsMandatory: False + # Values: ["Present", "Absent"] + newparam(:dsc_ensure) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Ensure - Specifies the membership of the database(s) in the availability group. The options are: Present: The defined database(s) are added to the availability group. All other databases that may be a member of the availability group are ignored. Absent: The defined database(s) are removed from the availability group. All other databases that may be a member of the availability group are ignored. The default is 'Present'. Valid values are Present, Absent." + validate do |value| + resource[:ensure] = value.downcase + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + unless ['Present', 'present', 'Absent', 'absent'].include?(value) + fail("Invalid value '#{value}'. Valid values are Present, Absent") + end + end + end + + # Name: Force + # Type: boolean + # IsMandatory: False + # Values: None + newparam(:dsc_force) do + def mof_type; 'boolean' end + def mof_is_embedded?; false end + desc "Force - When used with 'Ensure = 'Present'' it ensures the specified database(s) are the only databases that are a member of the specified Availability Group. This parameter is ignored when 'Ensure' is 'Absent'." + validate do |value| + end + newvalues(true, false) + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_boolean(value.to_s) + end + end + + # Name: MatchDatabaseOwner + # Type: boolean + # IsMandatory: False + # Values: None + newparam(:dsc_matchdatabaseowner) do + def mof_type; 'boolean' end + def mof_is_embedded?; false end + desc "MatchDatabaseOwner - If set to $true, this ensures the database owner of the database on the primary replica is the owner of the database on all secondary replicas. This requires the database owner is available as a login on all replicas and that the PSDscRunAsAccount has impersonate permissions. If set to $false, the owner of the database will be the PSDscRunAsAccount. The default is '$true'" + validate do |value| + end + newvalues(true, false) + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_boolean(value.to_s) + end + end + + # Name: ProcessOnlyOnActiveNode + # Type: boolean + # IsMandatory: False + # Values: None + newparam(:dsc_processonlyonactivenode) do + def mof_type; 'boolean' end + def mof_is_embedded?; false end + desc "ProcessOnlyOnActiveNode - Specifies that the resource will only determine if a change is needed if the target node is the active host of the SQL Server Instance." + validate do |value| + end + newvalues(true, false) + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_boolean(value.to_s) + end + end + + # Name: IsActiveNode + # Type: boolean + # IsMandatory: False + # Values: None + newparam(:dsc_isactivenode) do + def mof_type; 'boolean' end + def mof_is_embedded?; false end + desc "IsActiveNode - Determines if the current node is actively hosting the SQL Server instance." + validate do |value| + end + newvalues(true, false) + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_boolean(value.to_s) + end + end + + + def builddepends + pending_relations = super() + PuppetX::Dsc::TypeHelpers.ensure_reboot_relationship(self, pending_relations) + end +end + +Puppet::Type.type(:dsc_sqlagdatabase).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do + confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) + defaultfor :operatingsystem => :windows + + mk_resource_methods +end diff --git a/lib/puppet/type/dsc_xsqlserveravailabilitygrouplistener.rb b/lib/puppet/type/dsc_sqlaglistener.rb similarity index 87% rename from lib/puppet/type/dsc_xsqlserveravailabilitygrouplistener.rb rename to lib/puppet/type/dsc_sqlaglistener.rb index 415882043..87078f14c 100644 --- a/lib/puppet/type/dsc_xsqlserveravailabilitygrouplistener.rb +++ b/lib/puppet/type/dsc_sqlaglistener.rb @@ -1,14 +1,14 @@ require 'pathname' -Puppet::Type.newtype(:dsc_xsqlserveravailabilitygrouplistener) do +Puppet::Type.newtype(:dsc_sqlaglistener) do require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' @doc = %q{ - The DSC xSQLServerAvailabilityGroupListener resource type. + The DSC SqlAGListener resource type. Automatically generated from - 'xSQLServer/DSCResources/MSFT_xSQLServerAvailabilityGroupListener/MSFT_xSQLServerAvailabilityGroupListener.schema.mof' + 'SqlServerDsc/DSCResources/MSFT_SqlAGListener/MSFT_SqlAGListener.schema.mof' To learn more about PowerShell Desired State Configuration, please visit https://technet.microsoft.com/en-us/library/dn249912.aspx. @@ -25,10 +25,10 @@ fail('dsc_availabilitygroup is a required attribute') if self[:dsc_availabilitygroup].nil? end - def dscmeta_resource_friendly_name; 'xSQLServerAvailabilityGroupListener' end - def dscmeta_resource_name; 'MSFT_xSQLServerAvailabilityGroupListener' end - def dscmeta_module_name; 'xSQLServer' end - def dscmeta_module_version; '7.0.0.0' end + def dscmeta_resource_friendly_name; 'SqlAGListener' end + def dscmeta_resource_name; 'MSFT_SqlAGListener' end + def dscmeta_module_name; 'SqlServerDsc' end + def dscmeta_module_version; '11.0.0.0' end newparam(:name, :namevar => true ) do end @@ -72,14 +72,14 @@ def mof_is_embedded?; false end end end - # Name: NodeName + # Name: ServerName # Type: string # IsMandatory: False # Values: None - newparam(:dsc_nodename) do + newparam(:dsc_servername) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "NodeName - The host name or FQDN of the primary replica." + desc "ServerName - The host name or FQDN of the primary replica." validate do |value| unless value.kind_of?(String) fail("Invalid value '#{value}'. Should be a string") @@ -144,7 +144,7 @@ def mof_is_embedded?; false end newparam(:dsc_ipaddress, :array_matching => :all) do def mof_type; 'string[]' end def mof_is_embedded?; false end - desc "IpAddress - The IP address used for the availability group listener, in the format 192.168.10.45/255.255.252.0. If using DCHP, set to the first IP-address of the DHCP subnet, in the format 192.168.8.1/255.255.252.0. Must be valid in the cluster-allowed IP range." + desc "IpAddress - The IP address used for the availability group listener, in the format 192.168.10.45/255.255.252.0. If using DHCP, set to the first IP-address of the DHCP subnet, in the format 192.168.8.1/255.255.252.0. Must be valid in the cluster-allowed IP range." validate do |value| unless value.kind_of?(Array) || value.kind_of?(String) fail("Invalid value '#{value}'. Should be a string or an array of strings") @@ -196,7 +196,7 @@ def builddepends end end -Puppet::Type.type(:dsc_xsqlserveravailabilitygrouplistener).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do +Puppet::Type.type(:dsc_sqlaglistener).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) defaultfor :operatingsystem => :windows diff --git a/lib/puppet/type/dsc_xsqlserveralwaysonavailabilitygroupreplica.rb b/lib/puppet/type/dsc_sqlagreplica.rb similarity index 76% rename from lib/puppet/type/dsc_xsqlserveralwaysonavailabilitygroupreplica.rb rename to lib/puppet/type/dsc_sqlagreplica.rb index 15dad18a5..3f9fa149b 100644 --- a/lib/puppet/type/dsc_xsqlserveralwaysonavailabilitygroupreplica.rb +++ b/lib/puppet/type/dsc_sqlagreplica.rb @@ -1,14 +1,14 @@ require 'pathname' -Puppet::Type.newtype(:dsc_xsqlserveralwaysonavailabilitygroupreplica) do +Puppet::Type.newtype(:dsc_sqlagreplica) do require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' @doc = %q{ - The DSC xSQLServerAlwaysOnAvailabilityGroupReplica resource type. + The DSC SqlAGReplica resource type. Automatically generated from - 'xSQLServer/DSCResources/MSFT_xSQLServerAlwaysOnAvailabilityGroupReplica/MSFT_xSQLServerAlwaysOnAvailabilityGroupReplica.schema.mof' + 'SqlServerDsc/DSCResources/MSFT_SqlAGReplica/MSFT_SqlAGReplica.schema.mof' To learn more about PowerShell Desired State Configuration, please visit https://technet.microsoft.com/en-us/library/dn249912.aspx. @@ -23,13 +23,13 @@ validate do fail('dsc_name is a required attribute') if self[:dsc_name].nil? fail('dsc_availabilitygroupname is a required attribute') if self[:dsc_availabilitygroupname].nil? - fail('dsc_sqlinstancename is a required attribute') if self[:dsc_sqlinstancename].nil? + fail('dsc_instancename is a required attribute') if self[:dsc_instancename].nil? end - def dscmeta_resource_friendly_name; 'xSQLServerAlwaysOnAvailabilityGroupReplica' end - def dscmeta_resource_name; 'MSFT_xSQLServerAlwaysOnAvailabilityGroupReplica' end - def dscmeta_module_name; 'xSQLServer' end - def dscmeta_module_version; '7.0.0.0' end + def dscmeta_resource_friendly_name; 'SqlAGReplica' end + def dscmeta_resource_name; 'MSFT_SqlAGReplica' end + def dscmeta_module_name; 'SqlServerDsc' end + def dscmeta_module_version; '11.0.0.0' end newparam(:name, :namevar => true ) do end @@ -64,7 +64,7 @@ def mof_is_embedded?; true end newparam(:dsc_name) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "Name - The name of the availability group replica." + desc "Name - The name of the availability group replica. For named instances this must be in the following format ServerName\\InstanceName." isrequired validate do |value| unless value.kind_of?(String) @@ -89,14 +89,14 @@ def mof_is_embedded?; false end end end - # Name: SQLServer + # Name: ServerName # Type: string # IsMandatory: False # Values: None - newparam(:dsc_sqlserver) do + newparam(:dsc_servername) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "SQLServer - Hostname of the SQL Server to be configured." + desc "ServerName - Hostname of the SQL Server to be configured." validate do |value| unless value.kind_of?(String) fail("Invalid value '#{value}'. Should be a string") @@ -104,14 +104,14 @@ def mof_is_embedded?; false end end end - # Name: SQLInstanceName + # Name: InstanceName # Type: string # IsMandatory: True # Values: None - newparam(:dsc_sqlinstancename) do + newparam(:dsc_instancename) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "SQLInstanceName - Name of the SQL instance to be configued." + desc "InstanceName - Name of the SQL instance to be configured." isrequired validate do |value| unless value.kind_of?(String) @@ -120,14 +120,14 @@ def mof_is_embedded?; false end end end - # Name: PrimaryReplicaSQLServer + # Name: PrimaryReplicaServerName # Type: string # IsMandatory: False # Values: None - newparam(:dsc_primaryreplicasqlserver) do + newparam(:dsc_primaryreplicaservername) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "PrimaryReplicaSQLServer - Hostname of the SQL Server where the primary replica is expected to be active. If the primary replica is not found here, the resource will attempt to find the host that holds the primary replica and connect to it." + desc "PrimaryReplicaServerName - Hostname of the SQL Server where the primary replica is expected to be active. If the primary replica is not found here, the resource will attempt to find the host that holds the primary replica and connect to it." validate do |value| unless value.kind_of?(String) fail("Invalid value '#{value}'. Should be a string") @@ -135,14 +135,14 @@ def mof_is_embedded?; false end end end - # Name: PrimaryReplicaSQLInstanceName + # Name: PrimaryReplicaInstanceName # Type: string # IsMandatory: False # Values: None - newparam(:dsc_primaryreplicasqlinstancename) do + newparam(:dsc_primaryreplicainstancename) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "PrimaryReplicaSQLInstanceName - Name of the SQL instance where the primary replica lives." + desc "PrimaryReplicaInstanceName - Name of the SQL instance where the primary replica lives." validate do |value| unless value.kind_of?(String) fail("Invalid value '#{value}'. Should be a string") @@ -307,14 +307,48 @@ def mof_is_embedded?; false end end end - # Name: SqlServerNetName + # Name: ProcessOnlyOnActiveNode + # Type: boolean + # IsMandatory: False + # Values: None + newparam(:dsc_processonlyonactivenode) do + def mof_type; 'boolean' end + def mof_is_embedded?; false end + desc "ProcessOnlyOnActiveNode - Specifies that the resource will only determine if a change is needed if the target node is the active host of the SQL Server instance." + validate do |value| + end + newvalues(true, false) + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_boolean(value.to_s) + end + end + + # Name: EndpointPort + # Type: uint16 + # IsMandatory: False + # Values: None + newparam(:dsc_endpointport) do + def mof_type; 'uint16' end + def mof_is_embedded?; false end + desc "EndpointPort - Output the network port the endpoint is listening on. Used by Get-TargetResource." + validate do |value| + unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) + fail("Invalid value #{value}. Should be a unsigned Integer") + end + end + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_integer(value) + end + end + + # Name: EndpointUrl # Type: string # IsMandatory: False # Values: None - newparam(:dsc_sqlservernetname) do + newparam(:dsc_endpointurl) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "SqlServerNetName - Output the NetName property from the SQL Server object. Used by Get-TargetResource" + desc "EndpointUrl - Output the endpoint URL of the Availability Group Replica. Used by Get-TargetResource." validate do |value| unless value.kind_of?(String) fail("Invalid value '#{value}'. Should be a string") @@ -322,6 +356,22 @@ def mof_is_embedded?; false end end end + # Name: IsActiveNode + # Type: boolean + # IsMandatory: False + # Values: None + newparam(:dsc_isactivenode) do + def mof_type; 'boolean' end + def mof_is_embedded?; false end + desc "IsActiveNode - Determines if the current node is actively hosting the SQL Server instance." + validate do |value| + end + newvalues(true, false) + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_boolean(value.to_s) + end + end + def builddepends pending_relations = super() @@ -329,7 +379,7 @@ def builddepends end end -Puppet::Type.type(:dsc_xsqlserveralwaysonavailabilitygroupreplica).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do +Puppet::Type.type(:dsc_sqlagreplica).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) defaultfor :operatingsystem => :windows diff --git a/lib/puppet/type/dsc_xsqlserveralias.rb b/lib/puppet/type/dsc_sqlalias.rb similarity index 90% rename from lib/puppet/type/dsc_xsqlserveralias.rb rename to lib/puppet/type/dsc_sqlalias.rb index 0c58236b8..4fe3da934 100644 --- a/lib/puppet/type/dsc_xsqlserveralias.rb +++ b/lib/puppet/type/dsc_sqlalias.rb @@ -1,14 +1,14 @@ require 'pathname' -Puppet::Type.newtype(:dsc_xsqlserveralias) do +Puppet::Type.newtype(:dsc_sqlalias) do require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' @doc = %q{ - The DSC xSQLServerAlias resource type. + The DSC SqlAlias resource type. Automatically generated from - 'xSQLServer/DSCResources/MSFT_xSQLServerAlias/MSFT_xSQLServerAlias.schema.mof' + 'SqlServerDsc/DSCResources/MSFT_SqlAlias/MSFT_SqlAlias.schema.mof' To learn more about PowerShell Desired State Configuration, please visit https://technet.microsoft.com/en-us/library/dn249912.aspx. @@ -25,10 +25,10 @@ fail('dsc_servername is a required attribute') if self[:dsc_servername].nil? end - def dscmeta_resource_friendly_name; 'xSQLServerAlias' end - def dscmeta_resource_name; 'MSFT_xSQLServerAlias' end - def dscmeta_module_name; 'xSQLServer' end - def dscmeta_module_version; '7.0.0.0' end + def dscmeta_resource_friendly_name; 'SqlAlias' end + def dscmeta_resource_name; 'MSFT_SqlAlias' end + def dscmeta_module_name; 'SqlServerDsc' end + def dscmeta_module_version; '11.0.0.0' end newparam(:name, :namevar => true ) do end @@ -97,7 +97,7 @@ def mof_is_embedded?; false end newparam(:dsc_servername) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "ServerName - The SQL Server you are aliasing (the netbios name or FQDN)." + desc "ServerName - The SQL Server you are aliasing (the NetBIOS name or FQDN)." isrequired validate do |value| unless value.kind_of?(String) @@ -181,7 +181,7 @@ def builddepends end end -Puppet::Type.type(:dsc_xsqlserveralias).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do +Puppet::Type.type(:dsc_sqlalias).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) defaultfor :operatingsystem => :windows diff --git a/lib/puppet/type/dsc_xsqlservermaxdop.rb b/lib/puppet/type/dsc_sqlalwaysonservice.rb similarity index 64% rename from lib/puppet/type/dsc_xsqlservermaxdop.rb rename to lib/puppet/type/dsc_sqlalwaysonservice.rb index 26bf7c483..fcccb42b9 100644 --- a/lib/puppet/type/dsc_xsqlservermaxdop.rb +++ b/lib/puppet/type/dsc_sqlalwaysonservice.rb @@ -1,14 +1,14 @@ require 'pathname' -Puppet::Type.newtype(:dsc_xsqlservermaxdop) do +Puppet::Type.newtype(:dsc_sqlalwaysonservice) do require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' @doc = %q{ - The DSC xSQLServerMaxDop resource type. + The DSC SqlAlwaysOnService resource type. Automatically generated from - 'xSQLServer/DSCResources/MSFT_xSQLServerMaxDop/MSFT_xSQLServerMaxDop.schema.mof' + 'SqlServerDsc/DSCResources/MSFT_SqlAlwaysOnService/MSFT_SqlAlwaysOnService.schema.mof' To learn more about PowerShell Desired State Configuration, please visit https://technet.microsoft.com/en-us/library/dn249912.aspx. @@ -21,13 +21,14 @@ } validate do - fail('dsc_sqlinstancename is a required attribute') if self[:dsc_sqlinstancename].nil? + fail('dsc_servername is a required attribute') if self[:dsc_servername].nil? + fail('dsc_instancename is a required attribute') if self[:dsc_instancename].nil? end - def dscmeta_resource_friendly_name; 'xSQLServerMaxDop' end - def dscmeta_resource_name; 'MSFT_xSQLServerMaxDop' end - def dscmeta_module_name; 'xSQLServer' end - def dscmeta_module_version; '7.0.0.0' end + def dscmeta_resource_friendly_name; 'SqlAlwaysOnService' end + def dscmeta_resource_name; 'MSFT_SqlAlwaysOnService' end + def dscmeta_module_name; 'SqlServerDsc' end + def dscmeta_module_version; '11.0.0.0' end newparam(:name, :namevar => true ) do end @@ -62,7 +63,7 @@ def mof_is_embedded?; true end newparam(:dsc_ensure) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "Ensure - An enumerated value that describes if MaxDop is configured (Present) or reset to default value (Absent) Valid values are Present, Absent." + desc "Ensure - An enumerated value that describes if the SQL Server should have Always On high availability and disaster recovery (HADR) property enabled ('Present') or disabled ('Absent'). Valid values are Present, Absent." validate do |value| resource[:ensure] = value.downcase unless value.kind_of?(String) @@ -74,68 +75,69 @@ def mof_is_embedded?; false end end end - # Name: DynamicAlloc - # Type: boolean - # IsMandatory: False + # Name: ServerName + # Type: string + # IsMandatory: True # Values: None - newparam(:dsc_dynamicalloc) do - def mof_type; 'boolean' end + newparam(:dsc_servername) do + def mof_type; 'string' end def mof_is_embedded?; false end - desc "DynamicAlloc - Flag to Dynamically allocate Maxdop based on Best Practices" + desc "ServerName - The hostname of the SQL Server to be configured." + isrequired validate do |value| - end - newvalues(true, false) - munge do |value| - PuppetX::Dsc::TypeHelpers.munge_boolean(value.to_s) + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end end end - # Name: MaxDop - # Type: sint32 - # IsMandatory: False + # Name: InstanceName + # Type: string + # IsMandatory: True # Values: None - newparam(:dsc_maxdop) do - def mof_type; 'sint32' end + newparam(:dsc_instancename) do + def mof_type; 'string' end def mof_is_embedded?; false end - desc "MaxDop - Numeric value to configure Maxdop to" + desc "InstanceName - The name of the SQL instance to be configured." + isrequired validate do |value| - unless value.kind_of?(Numeric) || value.to_i.to_s == value - fail("Invalid value #{value}. Should be a signed Integer") + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") end end - munge do |value| - PuppetX::Dsc::TypeHelpers.munge_integer(value) - end end - # Name: SQLServer - # Type: string + # Name: RestartTimeout + # Type: uint32 # IsMandatory: False # Values: None - newparam(:dsc_sqlserver) do - def mof_type; 'string' end + newparam(:dsc_restarttimeout) do + def mof_type; 'uint32' end def mof_is_embedded?; false end - desc "SQLServer - The host name of the SQL Server to be configured. Default value is '$env:COMPUTERNAME'." + desc "RestartTimeout - The length of time, in seconds, to wait for the service to restart. Default is 120 seconds." validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") + unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) + fail("Invalid value #{value}. Should be a unsigned Integer") end end + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_integer(value) + end end - # Name: SQLInstanceName - # Type: string - # IsMandatory: True + # Name: IsHadrEnabled + # Type: boolean + # IsMandatory: False # Values: None - newparam(:dsc_sqlinstancename) do - def mof_type; 'string' end + newparam(:dsc_ishadrenabled) do + def mof_type; 'boolean' end def mof_is_embedded?; false end - desc "SQLInstanceName - The name of the SQL instance to be configured." - isrequired + desc "IsHadrEnabled - Returns the status of AlwaysOn high availability and disaster recovery (HADR)." validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end + end + newvalues(true, false) + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_boolean(value.to_s) end end @@ -146,7 +148,7 @@ def builddepends end end -Puppet::Type.type(:dsc_xsqlservermaxdop).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do +Puppet::Type.type(:dsc_sqlalwaysonservice).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) defaultfor :operatingsystem => :windows diff --git a/lib/puppet/type/dsc_xsqlserverdatabase.rb b/lib/puppet/type/dsc_sqldatabase.rb similarity index 72% rename from lib/puppet/type/dsc_xsqlserverdatabase.rb rename to lib/puppet/type/dsc_sqldatabase.rb index da59de55a..7f8bee622 100644 --- a/lib/puppet/type/dsc_xsqlserverdatabase.rb +++ b/lib/puppet/type/dsc_sqldatabase.rb @@ -1,14 +1,14 @@ require 'pathname' -Puppet::Type.newtype(:dsc_xsqlserverdatabase) do +Puppet::Type.newtype(:dsc_sqldatabase) do require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' @doc = %q{ - The DSC xSQLServerDatabase resource type. + The DSC SqlDatabase resource type. Automatically generated from - 'xSQLServer/DSCResources/MSFT_xSQLServerDatabase/MSFT_xSQLServerDatabase.schema.mof' + 'SqlServerDsc/DSCResources/MSFT_SqlDatabase/MSFT_SqlDatabase.schema.mof' To learn more about PowerShell Desired State Configuration, please visit https://technet.microsoft.com/en-us/library/dn249912.aspx. @@ -22,14 +22,14 @@ validate do fail('dsc_name is a required attribute') if self[:dsc_name].nil? - fail('dsc_sqlserver is a required attribute') if self[:dsc_sqlserver].nil? - fail('dsc_sqlinstancename is a required attribute') if self[:dsc_sqlinstancename].nil? + fail('dsc_servername is a required attribute') if self[:dsc_servername].nil? + fail('dsc_instancename is a required attribute') if self[:dsc_instancename].nil? end - def dscmeta_resource_friendly_name; 'xSQLServerDatabase' end - def dscmeta_resource_name; 'MSFT_xSQLServerDatabase' end - def dscmeta_module_name; 'xSQLServer' end - def dscmeta_module_version; '7.0.0.0' end + def dscmeta_resource_friendly_name; 'SqlDatabase' end + def dscmeta_resource_name; 'MSFT_SqlDatabase' end + def dscmeta_module_name; 'SqlServerDsc' end + def dscmeta_module_version; '11.0.0.0' end newparam(:name, :namevar => true ) do end @@ -92,14 +92,14 @@ def mof_is_embedded?; false end end end - # Name: SQLServer + # Name: ServerName # Type: string # IsMandatory: True # Values: None - newparam(:dsc_sqlserver) do + newparam(:dsc_servername) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "SQLServer - The host name of the SQL Server to be configured." + desc "ServerName - The host name of the SQL Server to be configured." isrequired validate do |value| unless value.kind_of?(String) @@ -108,14 +108,14 @@ def mof_is_embedded?; false end end end - # Name: SQLInstanceName + # Name: InstanceName # Type: string # IsMandatory: True # Values: None - newparam(:dsc_sqlinstancename) do + newparam(:dsc_instancename) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "SQLInstanceName - The name of the SQL instance to be configured." + desc "InstanceName - The name of the SQL instance to be configured." isrequired validate do |value| unless value.kind_of?(String) @@ -124,6 +124,21 @@ def mof_is_embedded?; false end end end + # Name: Collation + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_collation) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Collation - The name of the SQL collation to use for the new database. Defaults to server collation." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + def builddepends pending_relations = super() @@ -131,7 +146,7 @@ def builddepends end end -Puppet::Type.type(:dsc_xsqlserverdatabase).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do +Puppet::Type.type(:dsc_sqldatabase).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) defaultfor :operatingsystem => :windows diff --git a/lib/puppet/type/dsc_xsqlservernetwork.rb b/lib/puppet/type/dsc_sqldatabasedefaultlocation.rb similarity index 59% rename from lib/puppet/type/dsc_xsqlservernetwork.rb rename to lib/puppet/type/dsc_sqldatabasedefaultlocation.rb index bcff9a06c..ccb346e6f 100644 --- a/lib/puppet/type/dsc_xsqlservernetwork.rb +++ b/lib/puppet/type/dsc_sqldatabasedefaultlocation.rb @@ -1,14 +1,14 @@ require 'pathname' -Puppet::Type.newtype(:dsc_xsqlservernetwork) do +Puppet::Type.newtype(:dsc_sqldatabasedefaultlocation) do require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' @doc = %q{ - The DSC xSQLServerNetwork resource type. + The DSC SqlDatabaseDefaultLocation resource type. Automatically generated from - 'xSQLServer/DSCResources/MSFT_xSQLServerNetwork/MSFT_xSQLServerNetwork.schema.mof' + 'SqlServerDsc/DSCResources/MSFT_SqlDatabaseDefaultLocation/MSFT_SqlDatabaseDefaultLocation.schema.mof' To learn more about PowerShell Desired State Configuration, please visit https://technet.microsoft.com/en-us/library/dn249912.aspx. @@ -21,13 +21,15 @@ } validate do + fail('dsc_servername is a required attribute') if self[:dsc_servername].nil? fail('dsc_instancename is a required attribute') if self[:dsc_instancename].nil? + fail('dsc_type is a required attribute') if self[:dsc_type].nil? end - def dscmeta_resource_friendly_name; 'xSQLServerNetwork' end - def dscmeta_resource_name; 'MSFT_xSQLServerNetwork' end - def dscmeta_module_name; 'xSQLServer' end - def dscmeta_module_version; '7.0.0.0' end + def dscmeta_resource_friendly_name; 'SqlDatabaseDefaultLocation' end + def dscmeta_resource_name; 'MSFT_SqlDatabaseDefaultLocation' end + def dscmeta_module_name; 'SqlServerDsc' end + def dscmeta_module_version; '11.0.0.0' end newparam(:name, :namevar => true ) do end @@ -54,14 +56,14 @@ def mof_is_embedded?; true end end end - # Name: InstanceName + # Name: ServerName # Type: string # IsMandatory: True # Values: None - newparam(:dsc_instancename) do + newparam(:dsc_servername) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "InstanceName - SQL Server instance name of which network protocol should be configured" + desc "ServerName - The host name of the SQL Server to be configured." isrequired validate do |value| unless value.kind_of?(String) @@ -70,66 +72,49 @@ def mof_is_embedded?; false end end end - # Name: ProtocolName + # Name: InstanceName # Type: string - # IsMandatory: False - # Values: ["tcp"] - newparam(:dsc_protocolname) do + # IsMandatory: True + # Values: None + newparam(:dsc_instancename) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "ProtocolName - Network protocol name that should be configured Valid values are tcp." + desc "InstanceName - The name of the SQL instance to be configured." + isrequired validate do |value| unless value.kind_of?(String) fail("Invalid value '#{value}'. Should be a string") end - unless ['tcp', 'tcp'].include?(value) - fail("Invalid value '#{value}'. Valid values are tcp") - end - end - end - - # Name: IsEnabled - # Type: boolean - # IsMandatory: False - # Values: None - newparam(:dsc_isenabled) do - def mof_type; 'boolean' end - def mof_is_embedded?; false end - desc "IsEnabled - Is network protocol should be enabled or disabled" - validate do |value| - end - newvalues(true, false) - munge do |value| - PuppetX::Dsc::TypeHelpers.munge_boolean(value.to_s) end end - # Name: TCPDynamicPorts + # Name: Type # Type: string - # IsMandatory: False - # Values: ["0"] - newparam(:dsc_tcpdynamicports) do + # IsMandatory: True + # Values: ["Data", "Log", "Backup"] + newparam(:dsc_type) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "TCPDynamicPorts - If dynamic ports are used should be set to 0, otherwise leave empty Valid values are 0." + desc "Type - The type of database default location to be configured. { Data | Log | Backup } Valid values are Data, Log, Backup." + isrequired validate do |value| unless value.kind_of?(String) fail("Invalid value '#{value}'. Should be a string") end - unless ['0', '0'].include?(value) - fail("Invalid value '#{value}'. Valid values are 0") + unless ['Data', 'data', 'Log', 'log', 'Backup', 'backup'].include?(value) + fail("Invalid value '#{value}'. Valid values are Data, Log, Backup") end end end - # Name: TCPPort + # Name: Path # Type: string # IsMandatory: False # Values: None - newparam(:dsc_tcpport) do + newparam(:dsc_path) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "TCPPort - Sets static port for TCP/IP" + desc "Path - The path to the default directory to be configured." validate do |value| unless value.kind_of?(String) fail("Invalid value '#{value}'. Should be a string") @@ -144,7 +129,39 @@ def mof_is_embedded?; false end newparam(:dsc_restartservice) do def mof_type; 'boolean' end def mof_is_embedded?; false end - desc "RestartService - Controls if affected SQL Service should be restarted automatically" + desc "RestartService - If set to $true then SQL Server and dependent services will be restarted if a change to the default location is made. The defaul value is $false." + validate do |value| + end + newvalues(true, false) + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_boolean(value.to_s) + end + end + + # Name: ProcessOnlyOnActiveNode + # Type: boolean + # IsMandatory: False + # Values: None + newparam(:dsc_processonlyonactivenode) do + def mof_type; 'boolean' end + def mof_is_embedded?; false end + desc "ProcessOnlyOnActiveNode - Specifies that the resource will only determine if a change is needed if the target node is the active host of the SQL Server Instance." + validate do |value| + end + newvalues(true, false) + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_boolean(value.to_s) + end + end + + # Name: IsActiveNode + # Type: boolean + # IsMandatory: False + # Values: None + newparam(:dsc_isactivenode) do + def mof_type; 'boolean' end + def mof_is_embedded?; false end + desc "IsActiveNode - Determines if the current node is actively hosting the SQL Server instance." validate do |value| end newvalues(true, false) @@ -160,7 +177,7 @@ def builddepends end end -Puppet::Type.type(:dsc_xsqlservernetwork).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do +Puppet::Type.type(:dsc_sqldatabasedefaultlocation).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) defaultfor :operatingsystem => :windows diff --git a/lib/puppet/type/dsc_xsqlserverdatabaseowner.rb b/lib/puppet/type/dsc_sqldatabaseowner.rb similarity index 79% rename from lib/puppet/type/dsc_xsqlserverdatabaseowner.rb rename to lib/puppet/type/dsc_sqldatabaseowner.rb index fa74d8196..964a0e6ec 100644 --- a/lib/puppet/type/dsc_xsqlserverdatabaseowner.rb +++ b/lib/puppet/type/dsc_sqldatabaseowner.rb @@ -1,14 +1,14 @@ require 'pathname' -Puppet::Type.newtype(:dsc_xsqlserverdatabaseowner) do +Puppet::Type.newtype(:dsc_sqldatabaseowner) do require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' @doc = %q{ - The DSC xSQLServerDatabaseOwner resource type. + The DSC SqlDatabaseOwner resource type. Automatically generated from - 'xSQLServer/DSCResources/MSFT_xSQLServerDatabaseOwner/MSFT_xSQLServerDatabaseOwner.schema.mof' + 'SqlServerDsc/DSCResources/MSFT_SqlDatabaseOwner/MSFT_SqlDatabaseOwner.schema.mof' To learn more about PowerShell Desired State Configuration, please visit https://technet.microsoft.com/en-us/library/dn249912.aspx. @@ -24,10 +24,10 @@ fail('dsc_database is a required attribute') if self[:dsc_database].nil? end - def dscmeta_resource_friendly_name; 'xSQLServerDatabaseOwner' end - def dscmeta_resource_name; 'MSFT_xSQLServerDatabaseOwner' end - def dscmeta_module_name; 'xSQLServer' end - def dscmeta_module_version; '7.0.0.0' end + def dscmeta_resource_friendly_name; 'SqlDatabaseOwner' end + def dscmeta_resource_name; 'MSFT_SqlDatabaseOwner' end + def dscmeta_module_name; 'SqlServerDsc' end + def dscmeta_module_version; '11.0.0.0' end newparam(:name, :namevar => true ) do end @@ -85,14 +85,14 @@ def mof_is_embedded?; false end end end - # Name: SQLServer + # Name: ServerName # Type: string # IsMandatory: False # Values: None - newparam(:dsc_sqlserver) do + newparam(:dsc_servername) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "SQLServer - The host name of the SQL Server to be configured." + desc "ServerName - The host name of the SQL Server to be configured." validate do |value| unless value.kind_of?(String) fail("Invalid value '#{value}'. Should be a string") @@ -100,14 +100,14 @@ def mof_is_embedded?; false end end end - # Name: SQLInstanceName + # Name: InstanceName # Type: string # IsMandatory: False # Values: None - newparam(:dsc_sqlinstancename) do + newparam(:dsc_instancename) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "SQLInstanceName - The name of the SQL instance to be configured." + desc "InstanceName - The name of the SQL instance to be configured." validate do |value| unless value.kind_of?(String) fail("Invalid value '#{value}'. Should be a string") @@ -122,7 +122,7 @@ def builddepends end end -Puppet::Type.type(:dsc_xsqlserverdatabaseowner).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do +Puppet::Type.type(:dsc_sqldatabaseowner).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) defaultfor :operatingsystem => :windows diff --git a/lib/puppet/type/dsc_xsqlserverdatabasepermission.rb b/lib/puppet/type/dsc_sqldatabasepermission.rb similarity index 80% rename from lib/puppet/type/dsc_xsqlserverdatabasepermission.rb rename to lib/puppet/type/dsc_sqldatabasepermission.rb index 5a3122c19..b209c8fda 100644 --- a/lib/puppet/type/dsc_xsqlserverdatabasepermission.rb +++ b/lib/puppet/type/dsc_sqldatabasepermission.rb @@ -1,14 +1,14 @@ require 'pathname' -Puppet::Type.newtype(:dsc_xsqlserverdatabasepermission) do +Puppet::Type.newtype(:dsc_sqldatabasepermission) do require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' @doc = %q{ - The DSC xSQLServerDatabasePermission resource type. + The DSC SqlDatabasePermission resource type. Automatically generated from - 'xSQLServer/DSCResources/MSFT_xSQLServerDatabasePermission/MSFT_xSQLServerDatabasePermission.schema.mof' + 'SqlServerDsc/DSCResources/MSFT_SqlDatabasePermission/MSFT_SqlDatabasePermission.schema.mof' To learn more about PowerShell Desired State Configuration, please visit https://technet.microsoft.com/en-us/library/dn249912.aspx. @@ -24,14 +24,14 @@ fail('dsc_database is a required attribute') if self[:dsc_database].nil? fail('dsc_name is a required attribute') if self[:dsc_name].nil? fail('dsc_permissionstate is a required attribute') if self[:dsc_permissionstate].nil? - fail('dsc_sqlserver is a required attribute') if self[:dsc_sqlserver].nil? - fail('dsc_sqlinstancename is a required attribute') if self[:dsc_sqlinstancename].nil? + fail('dsc_servername is a required attribute') if self[:dsc_servername].nil? + fail('dsc_instancename is a required attribute') if self[:dsc_instancename].nil? end - def dscmeta_resource_friendly_name; 'xSQLServerDatabasePermission' end - def dscmeta_resource_name; 'MSFT_xSQLServerDatabasePermission' end - def dscmeta_module_name; 'xSQLServer' end - def dscmeta_module_version; '7.0.0.0' end + def dscmeta_resource_friendly_name; 'SqlDatabasePermission' end + def dscmeta_resource_name; 'MSFT_SqlDatabasePermission' end + def dscmeta_module_name; 'SqlServerDsc' end + def dscmeta_module_version; '11.0.0.0' end newparam(:name, :namevar => true ) do end @@ -113,18 +113,18 @@ def mof_is_embedded?; false end # Name: PermissionState # Type: string # IsMandatory: True - # Values: ["Grant", "Deny"] + # Values: ["Grant", "Deny", "GrantWithGrant"] newparam(:dsc_permissionstate) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "PermissionState - The state of the permission. Valid values are 'Grant' or 'Deny'. Valid values are Grant, Deny." + desc "PermissionState - The state of the permission. Valid values are 'Grant' or 'Deny'. Valid values are Grant, Deny, GrantWithGrant." isrequired validate do |value| unless value.kind_of?(String) fail("Invalid value '#{value}'. Should be a string") end - unless ['Grant', 'grant', 'Deny', 'deny'].include?(value) - fail("Invalid value '#{value}'. Valid values are Grant, Deny") + unless ['Grant', 'grant', 'Deny', 'deny', 'GrantWithGrant', 'grantwithgrant'].include?(value) + fail("Invalid value '#{value}'. Valid values are Grant, Deny, GrantWithGrant") end end end @@ -147,14 +147,14 @@ def mof_is_embedded?; false end end end - # Name: SQLServer + # Name: ServerName # Type: string # IsMandatory: True # Values: None - newparam(:dsc_sqlserver) do + newparam(:dsc_servername) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "SQLServer - The host name of the SQL Server to be configured." + desc "ServerName - The host name of the SQL Server to be configured." isrequired validate do |value| unless value.kind_of?(String) @@ -163,14 +163,14 @@ def mof_is_embedded?; false end end end - # Name: SQLInstanceName + # Name: InstanceName # Type: string # IsMandatory: True # Values: None - newparam(:dsc_sqlinstancename) do + newparam(:dsc_instancename) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "SQLInstanceName - The name of the SQL instance to be configured." + desc "InstanceName - The name of the SQL instance to be configured." isrequired validate do |value| unless value.kind_of?(String) @@ -186,7 +186,7 @@ def builddepends end end -Puppet::Type.type(:dsc_xsqlserverdatabasepermission).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do +Puppet::Type.type(:dsc_sqldatabasepermission).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) defaultfor :operatingsystem => :windows diff --git a/lib/puppet/type/dsc_xsqlserverdatabaserecoverymodel.rb b/lib/puppet/type/dsc_sqldatabaserecoverymodel.rb similarity index 76% rename from lib/puppet/type/dsc_xsqlserverdatabaserecoverymodel.rb rename to lib/puppet/type/dsc_sqldatabaserecoverymodel.rb index b1512c657..04e806a53 100644 --- a/lib/puppet/type/dsc_xsqlserverdatabaserecoverymodel.rb +++ b/lib/puppet/type/dsc_sqldatabaserecoverymodel.rb @@ -1,14 +1,14 @@ require 'pathname' -Puppet::Type.newtype(:dsc_xsqlserverdatabaserecoverymodel) do +Puppet::Type.newtype(:dsc_sqldatabaserecoverymodel) do require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' @doc = %q{ - The DSC xSQLServerDatabaseRecoveryModel resource type. + The DSC SqlDatabaseRecoveryModel resource type. Automatically generated from - 'xSQLServer/DSCResources/MSFT_xSQLServerDatabaseRecoveryModel/MSFT_xSQLServerDatabaseRecoveryModel.schema.mof' + 'SqlServerDsc/DSCResources/MSFT_SqlDatabaseRecoveryModel/MSFT_SqlDatabaseRecoveryModel.schema.mof' To learn more about PowerShell Desired State Configuration, please visit https://technet.microsoft.com/en-us/library/dn249912.aspx. @@ -22,14 +22,14 @@ validate do fail('dsc_name is a required attribute') if self[:dsc_name].nil? - fail('dsc_sqlserver is a required attribute') if self[:dsc_sqlserver].nil? - fail('dsc_sqlinstancename is a required attribute') if self[:dsc_sqlinstancename].nil? + fail('dsc_servername is a required attribute') if self[:dsc_servername].nil? + fail('dsc_instancename is a required attribute') if self[:dsc_instancename].nil? end - def dscmeta_resource_friendly_name; 'xSQLServerDatabaseRecoveryModel' end - def dscmeta_resource_name; 'MSFT_xSQLServerDatabaseRecoveryModel' end - def dscmeta_module_name; 'xSQLServer' end - def dscmeta_module_version; '7.0.0.0' end + def dscmeta_resource_friendly_name; 'SqlDatabaseRecoveryModel' end + def dscmeta_resource_name; 'MSFT_SqlDatabaseRecoveryModel' end + def dscmeta_module_name; 'SqlServerDsc' end + def dscmeta_module_version; '11.0.0.0' end newparam(:name, :namevar => true ) do end @@ -90,14 +90,14 @@ def mof_is_embedded?; false end end end - # Name: SQLServer + # Name: ServerName # Type: string # IsMandatory: True # Values: None - newparam(:dsc_sqlserver) do + newparam(:dsc_servername) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "SQLServer - The host name of the SQL Server to be configured." + desc "ServerName - The host name of the SQL Server to be configured." isrequired validate do |value| unless value.kind_of?(String) @@ -106,14 +106,14 @@ def mof_is_embedded?; false end end end - # Name: SQLInstanceName + # Name: InstanceName # Type: string # IsMandatory: True # Values: None - newparam(:dsc_sqlinstancename) do + newparam(:dsc_instancename) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "SQLInstanceName - The name of the SQL instance to be configured." + desc "InstanceName - The name of the SQL instance to be configured." isrequired validate do |value| unless value.kind_of?(String) @@ -129,7 +129,7 @@ def builddepends end end -Puppet::Type.type(:dsc_xsqlserverdatabaserecoverymodel).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do +Puppet::Type.type(:dsc_sqldatabaserecoverymodel).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) defaultfor :operatingsystem => :windows diff --git a/lib/puppet/type/dsc_xsqlserverdatabaserole.rb b/lib/puppet/type/dsc_sqldatabaserole.rb similarity index 82% rename from lib/puppet/type/dsc_xsqlserverdatabaserole.rb rename to lib/puppet/type/dsc_sqldatabaserole.rb index 379ace272..088c3fd8f 100644 --- a/lib/puppet/type/dsc_xsqlserverdatabaserole.rb +++ b/lib/puppet/type/dsc_sqldatabaserole.rb @@ -1,14 +1,14 @@ require 'pathname' -Puppet::Type.newtype(:dsc_xsqlserverdatabaserole) do +Puppet::Type.newtype(:dsc_sqldatabaserole) do require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' @doc = %q{ - The DSC xSQLServerDatabaseRole resource type. + The DSC SqlDatabaseRole resource type. Automatically generated from - 'xSQLServer/DSCResources/MSFT_xSQLServerDatabaseRole/MSFT_xSQLServerDatabaseRole.schema.mof' + 'SqlServerDsc/DSCResources/MSFT_SqlDatabaseRole/MSFT_SqlDatabaseRole.schema.mof' To learn more about PowerShell Desired State Configuration, please visit https://technet.microsoft.com/en-us/library/dn249912.aspx. @@ -22,15 +22,15 @@ validate do fail('dsc_name is a required attribute') if self[:dsc_name].nil? - fail('dsc_sqlserver is a required attribute') if self[:dsc_sqlserver].nil? - fail('dsc_sqlinstancename is a required attribute') if self[:dsc_sqlinstancename].nil? + fail('dsc_servername is a required attribute') if self[:dsc_servername].nil? + fail('dsc_instancename is a required attribute') if self[:dsc_instancename].nil? fail('dsc_database is a required attribute') if self[:dsc_database].nil? end - def dscmeta_resource_friendly_name; 'xSQLServerDatabaseRole' end - def dscmeta_resource_name; 'MSFT_xSQLServerDatabaseRole' end - def dscmeta_module_name; 'xSQLServer' end - def dscmeta_module_version; '7.0.0.0' end + def dscmeta_resource_friendly_name; 'SqlDatabaseRole' end + def dscmeta_resource_name; 'MSFT_SqlDatabaseRole' end + def dscmeta_module_name; 'SqlServerDsc' end + def dscmeta_module_version; '11.0.0.0' end newparam(:name, :namevar => true ) do end @@ -93,14 +93,14 @@ def mof_is_embedded?; false end end end - # Name: SQLServer + # Name: ServerName # Type: string # IsMandatory: True # Values: None - newparam(:dsc_sqlserver) do + newparam(:dsc_servername) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "SQLServer - The host name of the SQL Server to be configured." + desc "ServerName - The host name of the SQL Server to be configured." isrequired validate do |value| unless value.kind_of?(String) @@ -109,14 +109,14 @@ def mof_is_embedded?; false end end end - # Name: SQLInstanceName + # Name: InstanceName # Type: string # IsMandatory: True # Values: None - newparam(:dsc_sqlinstancename) do + newparam(:dsc_instancename) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "SQLInstanceName - The name of the SQL instance to be configured." + desc "InstanceName - The name of the SQL instance to be configured." isrequired validate do |value| unless value.kind_of?(String) @@ -166,7 +166,7 @@ def builddepends end end -Puppet::Type.type(:dsc_xsqlserverdatabaserole).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do +Puppet::Type.type(:dsc_sqldatabaserole).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) defaultfor :operatingsystem => :windows diff --git a/lib/puppet/type/dsc_sqlrs.rb b/lib/puppet/type/dsc_sqlrs.rb new file mode 100644 index 000000000..81f2f1dc4 --- /dev/null +++ b/lib/puppet/type/dsc_sqlrs.rb @@ -0,0 +1,213 @@ +require 'pathname' + +Puppet::Type.newtype(:dsc_sqlrs) do + require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' + require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' + + + @doc = %q{ + The DSC SqlRS resource type. + Automatically generated from + 'SqlServerDsc/DSCResources/MSFT_SqlRS/MSFT_SqlRS.schema.mof' + + To learn more about PowerShell Desired State Configuration, please + visit https://technet.microsoft.com/en-us/library/dn249912.aspx. + + For more information about built-in DSC Resources, please visit + https://technet.microsoft.com/en-us/library/dn249921.aspx. + + For more information about xDsc Resources, please visit + https://github.com/PowerShell/DscResources. + } + + validate do + fail('dsc_instancename is a required attribute') if self[:dsc_instancename].nil? + end + + def dscmeta_resource_friendly_name; 'SqlRS' end + def dscmeta_resource_name; 'MSFT_SqlRS' end + def dscmeta_module_name; 'SqlServerDsc' end + def dscmeta_module_version; '11.0.0.0' end + + newparam(:name, :namevar => true ) do + end + + ensurable do + newvalue(:exists?) { provider.exists? } + newvalue(:present) { provider.create } + defaultto { :present } + end + + # Name: PsDscRunAsCredential + # Type: MSFT_Credential + # IsMandatory: False + # Values: None + newparam(:dsc_psdscrunascredential) do + def mof_type; 'MSFT_Credential' end + def mof_is_embedded?; true end + desc "PsDscRunAsCredential" + validate do |value| + unless value.kind_of?(Hash) + fail("Invalid value '#{value}'. Should be a hash") + end + PuppetX::Dsc::TypeHelpers.validate_MSFT_Credential("Credential", value) + end + end + + # Name: InstanceName + # Type: string + # IsMandatory: True + # Values: None + newparam(:dsc_instancename) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "InstanceName - Name of the SQL Server Reporting Services instance to be configured." + isrequired + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: DatabaseServerName + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_databaseservername) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "DatabaseServerName - Name of the SQL Server to host the Reporting Service database." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: DatabaseInstanceName + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_databaseinstancename) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "DatabaseInstanceName - Name of the SQL Server instance to host the Reporting Service database." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: ReportServerVirtualDirectory + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_reportservervirtualdirectory) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "ReportServerVirtualDirectory - Report Server Web Service virtual directory. Optional." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: ReportsVirtualDirectory + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_reportsvirtualdirectory) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "ReportsVirtualDirectory - Report Manager/Report Web App virtual directory name. Optional." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: ReportServerReservedUrl + # Type: string[] + # IsMandatory: False + # Values: None + newparam(:dsc_reportserverreservedurl, :array_matching => :all) do + def mof_type; 'string[]' end + def mof_is_embedded?; false end + desc "ReportServerReservedUrl - Report Server URL reservations. Optional. If not specified, 'http://+:80' URL reservation will be used." + validate do |value| + unless value.kind_of?(Array) || value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string or an array of strings") + end + end + munge do |value| + Array(value) + end + end + + # Name: ReportsReservedUrl + # Type: string[] + # IsMandatory: False + # Values: None + newparam(:dsc_reportsreservedurl, :array_matching => :all) do + def mof_type; 'string[]' end + def mof_is_embedded?; false end + desc "ReportsReservedUrl - Report Manager/Report Web App URL reservations. Optional. If not specified, 'http://+:80' URL reservation will be used." + validate do |value| + unless value.kind_of?(Array) || value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string or an array of strings") + end + end + munge do |value| + Array(value) + end + end + + # Name: UseSsl + # Type: boolean + # IsMandatory: False + # Values: None + newparam(:dsc_usessl) do + def mof_type; 'boolean' end + def mof_is_embedded?; false end + desc "UseSsl - If connections to the Reporting Services must use SSL. If this parameter is not assigned a value, the default is that Reporting Services does not use SSL." + validate do |value| + end + newvalues(true, false) + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_boolean(value.to_s) + end + end + + # Name: IsInitialized + # Type: boolean + # IsMandatory: False + # Values: None + newparam(:dsc_isinitialized) do + def mof_type; 'boolean' end + def mof_is_embedded?; false end + desc "IsInitialized - Is the Reporting Services instance initialized." + validate do |value| + end + newvalues(true, false) + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_boolean(value.to_s) + end + end + + + def builddepends + pending_relations = super() + PuppetX::Dsc::TypeHelpers.ensure_reboot_relationship(self, pending_relations) + end +end + +Puppet::Type.type(:dsc_sqlrs).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do + confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) + defaultfor :operatingsystem => :windows + + mk_resource_methods +end diff --git a/lib/puppet/type/dsc_xsqlserverscript.rb b/lib/puppet/type/dsc_sqlscript.rb similarity index 77% rename from lib/puppet/type/dsc_xsqlserverscript.rb rename to lib/puppet/type/dsc_sqlscript.rb index d38ca1674..bf4d580c3 100644 --- a/lib/puppet/type/dsc_xsqlserverscript.rb +++ b/lib/puppet/type/dsc_sqlscript.rb @@ -1,14 +1,14 @@ require 'pathname' -Puppet::Type.newtype(:dsc_xsqlserverscript) do +Puppet::Type.newtype(:dsc_sqlscript) do require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' @doc = %q{ - The DSC xSQLServerScript resource type. + The DSC SqlScript resource type. Automatically generated from - 'xSQLServer/DSCResources/MSFT_xSQLServerScript/MSFT_xSQLServerScript.schema.mof' + 'SqlServerDsc/DSCResources/MSFT_SqlScript/MSFT_SqlScript.schema.mof' To learn more about PowerShell Desired State Configuration, please visit https://technet.microsoft.com/en-us/library/dn249912.aspx. @@ -27,10 +27,10 @@ fail('dsc_testfilepath is a required attribute') if self[:dsc_testfilepath].nil? end - def dscmeta_resource_friendly_name; 'xSQLServerScript' end - def dscmeta_resource_name; 'MSFT_xSQLServerScript' end - def dscmeta_module_name; 'xSQLServer' end - def dscmeta_module_version; '7.0.0.0' end + def dscmeta_resource_friendly_name; 'SqlScript' end + def dscmeta_resource_name; 'MSFT_SqlScript' end + def dscmeta_module_name; 'SqlServerDsc' end + def dscmeta_module_version; '11.0.0.0' end newparam(:name, :namevar => true ) do end @@ -112,7 +112,7 @@ def mof_is_embedded?; false end newparam(:dsc_testfilepath) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "TestFilePath - Path to the T-SQL file that will perform Test action. Any script that does not throw an error or returns null is evaluated to true. The cmdlet Invoke-SqlCmd treats T-SQL Print statements as verbose text, and will not cause the test to return false." + desc "TestFilePath - Path to the T-SQL file that will perform Test action. Any script that does not throw an error or returns null is evaluated to true. The cmdlet Invoke-Sqlcmd treats T-SQL Print statements as verbose text, and will not cause the test to return false." isrequired validate do |value| unless value.kind_of?(String) @@ -144,7 +144,7 @@ def mof_is_embedded?; true end newparam(:dsc_variable, :array_matching => :all) do def mof_type; 'string[]' end def mof_is_embedded?; false end - desc "Variable - Specifies, as a string array, a sqlcmd scripting variable for use in the sqlcmd script, and sets a value for the variable. Use a Windows PowerShell array to specify multiple variables and their values. For more information how to use this, please go to the help documentation for Invoke-Sqlcmd." + desc "Variable - Specifies, as a string array, a scripting variable for use in the sql script, and sets a value for the variable. Use a Windows PowerShell array to specify multiple variables and their values. For more information how to use this, please go to the help documentation for [Invoke-Sqlcmd](https://technet.microsoft.com/en-us/library/mt683370.aspx)" validate do |value| unless value.kind_of?(Array) || value.kind_of?(String) fail("Invalid value '#{value}'. Should be a string or an array of strings") @@ -155,6 +155,24 @@ def mof_is_embedded?; false end end end + # Name: QueryTimeout + # Type: uint32 + # IsMandatory: False + # Values: None + newparam(:dsc_querytimeout) do + def mof_type; 'uint32' end + def mof_is_embedded?; false end + desc "QueryTimeout - Specifies, as an integer, the number of seconds after which the T-SQL script execution will time out. In some SQL Server versions there is a bug in Invoke-Sqlcmd where the normal default value 0 (no timeout) is not respected and the default value is incorrectly set to 30 seconds." + validate do |value| + unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) + fail("Invalid value #{value}. Should be a unsigned Integer") + end + end + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_integer(value) + end + end + # Name: GetResult # Type: string[] # IsMandatory: False @@ -180,7 +198,7 @@ def builddepends end end -Puppet::Type.type(:dsc_xsqlserverscript).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do +Puppet::Type.type(:dsc_sqlscript).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) defaultfor :operatingsystem => :windows diff --git a/lib/puppet/type/dsc_xsqlserverconfiguration.rb b/lib/puppet/type/dsc_sqlserverconfiguration.rb similarity index 77% rename from lib/puppet/type/dsc_xsqlserverconfiguration.rb rename to lib/puppet/type/dsc_sqlserverconfiguration.rb index eb55227a9..c82f2e12d 100644 --- a/lib/puppet/type/dsc_xsqlserverconfiguration.rb +++ b/lib/puppet/type/dsc_sqlserverconfiguration.rb @@ -1,14 +1,14 @@ require 'pathname' -Puppet::Type.newtype(:dsc_xsqlserverconfiguration) do +Puppet::Type.newtype(:dsc_sqlserverconfiguration) do require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' @doc = %q{ - The DSC xSQLServerConfiguration resource type. + The DSC SqlServerConfiguration resource type. Automatically generated from - 'xSQLServer/DSCResources/MSFT_xSQLServerConfiguration/MSFT_xSQLServerConfiguration.schema.mof' + 'SqlServerDsc/DSCResources/MSFT_SqlServerConfiguration/MSFT_SqlServerConfiguration.schema.mof' To learn more about PowerShell Desired State Configuration, please visit https://technet.microsoft.com/en-us/library/dn249912.aspx. @@ -21,15 +21,15 @@ } validate do - fail('dsc_sqlserver is a required attribute') if self[:dsc_sqlserver].nil? - fail('dsc_sqlinstancename is a required attribute') if self[:dsc_sqlinstancename].nil? + fail('dsc_servername is a required attribute') if self[:dsc_servername].nil? + fail('dsc_instancename is a required attribute') if self[:dsc_instancename].nil? fail('dsc_optionname is a required attribute') if self[:dsc_optionname].nil? end - def dscmeta_resource_friendly_name; 'xSQLServerConfiguration' end - def dscmeta_resource_name; 'MSFT_xSQLServerConfiguration' end - def dscmeta_module_name; 'xSQLServer' end - def dscmeta_module_version; '7.0.0.0' end + def dscmeta_resource_friendly_name; 'SqlServerConfiguration' end + def dscmeta_resource_name; 'MSFT_SqlServerConfiguration' end + def dscmeta_module_name; 'SqlServerDsc' end + def dscmeta_module_version; '11.0.0.0' end newparam(:name, :namevar => true ) do end @@ -56,14 +56,14 @@ def mof_is_embedded?; true end end end - # Name: SQLServer + # Name: ServerName # Type: string # IsMandatory: True # Values: None - newparam(:dsc_sqlserver) do + newparam(:dsc_servername) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "SQLServer - The hostname of the SQL Server to be configured." + desc "ServerName - The hostname of the SQL Server to be configured." isrequired validate do |value| unless value.kind_of?(String) @@ -72,14 +72,14 @@ def mof_is_embedded?; false end end end - # Name: SQLInstanceName + # Name: InstanceName # Type: string # IsMandatory: True # Values: None - newparam(:dsc_sqlinstancename) do + newparam(:dsc_instancename) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "SQLInstanceName - Name of the SQL instance to be configured." + desc "InstanceName - Name of the SQL instance to be configured." isrequired validate do |value| unless value.kind_of?(String) @@ -139,16 +139,16 @@ def mof_is_embedded?; false end end # Name: RestartTimeout - # Type: sint32 + # Type: uint32 # IsMandatory: False # Values: None newparam(:dsc_restarttimeout) do - def mof_type; 'sint32' end + def mof_type; 'uint32' end def mof_is_embedded?; false end desc "RestartTimeout - The length of time, in seconds, to wait for the service to restart. Default is 120 seconds." validate do |value| - unless value.kind_of?(Numeric) || value.to_i.to_s == value - fail("Invalid value #{value}. Should be a signed Integer") + unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) + fail("Invalid value #{value}. Should be a unsigned Integer") end end munge do |value| @@ -163,7 +163,7 @@ def builddepends end end -Puppet::Type.type(:dsc_xsqlserverconfiguration).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do +Puppet::Type.type(:dsc_sqlserverconfiguration).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) defaultfor :operatingsystem => :windows diff --git a/lib/puppet/type/dsc_xsqlaogroupensure.rb b/lib/puppet/type/dsc_sqlserverdatabasemail.rb similarity index 50% rename from lib/puppet/type/dsc_xsqlaogroupensure.rb rename to lib/puppet/type/dsc_sqlserverdatabasemail.rb index 6703f41c0..7e6df25bb 100644 --- a/lib/puppet/type/dsc_xsqlaogroupensure.rb +++ b/lib/puppet/type/dsc_sqlserverdatabasemail.rb @@ -1,14 +1,14 @@ require 'pathname' -Puppet::Type.newtype(:dsc_xsqlaogroupensure) do +Puppet::Type.newtype(:dsc_sqlserverdatabasemail) do require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' @doc = %q{ - The DSC xSQLAOGroupEnsure resource type. + The DSC SqlServerDatabaseMail resource type. Automatically generated from - 'xSQLServer/DSCResources/MSFT_xSQLAOGroupEnsure/MSFT_xSQLAOGroupEnsure.schema.mof' + 'SqlServerDsc/DSCResources/MSFT_SqlServerDatabaseMail/MSFT_SqlServerDatabaseMail.schema.mof' To learn more about PowerShell Desired State Configuration, please visit https://technet.microsoft.com/en-us/library/dn249912.aspx. @@ -21,14 +21,14 @@ } validate do - fail('dsc_ensure is a required attribute') if self[:dsc_ensure].nil? - fail('dsc_availabilitygroupname is a required attribute') if self[:dsc_availabilitygroupname].nil? + fail('dsc_accountname is a required attribute') if self[:dsc_accountname].nil? + fail('dsc_instancename is a required attribute') if self[:dsc_instancename].nil? end - def dscmeta_resource_friendly_name; 'xSQLAOGroupEnsure' end - def dscmeta_resource_name; 'MSFT_xSQLAOGroupEnsure' end - def dscmeta_module_name; 'xSQLServer' end - def dscmeta_module_version; '7.0.0.0' end + def dscmeta_resource_friendly_name; 'SqlServerDatabaseMail' end + def dscmeta_resource_name; 'MSFT_SqlServerDatabaseMail' end + def dscmeta_module_name; 'SqlServerDsc' end + def dscmeta_module_version; '11.0.0.0' end newparam(:name, :namevar => true ) do end @@ -56,34 +56,30 @@ def mof_is_embedded?; true end end end - # Name: Ensure + # Name: AccountName # Type: string # IsMandatory: True - # Values: ["Present", "Absent"] - newparam(:dsc_ensure) do + # Values: None + newparam(:dsc_accountname) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "Ensure - Determines whether the availability group should be added or removed. Valid values are Present, Absent." + desc "AccountName - The name of the Database Mail account." isrequired validate do |value| - resource[:ensure] = value.downcase unless value.kind_of?(String) fail("Invalid value '#{value}'. Should be a string") end - unless ['Present', 'present', 'Absent', 'absent'].include?(value) - fail("Invalid value '#{value}'. Valid values are Present, Absent") - end end end - # Name: AvailabilityGroupName + # Name: InstanceName # Type: string # IsMandatory: True # Values: None - newparam(:dsc_availabilitygroupname) do + newparam(:dsc_instancename) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "AvailabilityGroupName - Name for availability group." + desc "InstanceName - The name of the SQL instance to be configured." isrequired validate do |value| unless value.kind_of?(String) @@ -92,14 +88,14 @@ def mof_is_embedded?; false end end end - # Name: AvailabilityGroupNameListener + # Name: EmailAddress # Type: string # IsMandatory: False # Values: None - newparam(:dsc_availabilitygroupnamelistener) do + newparam(:dsc_emailaddress) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "AvailabilityGroupNameListener - Listener name for availability group." + desc "EmailAddress - The e-mail address from which mail will originate." validate do |value| unless value.kind_of?(String) fail("Invalid value '#{value}'. Should be a string") @@ -107,140 +103,108 @@ def mof_is_embedded?; false end end end - # Name: AvailabilityGroupNameIP - # Type: string[] - # IsMandatory: False - # Values: None - newparam(:dsc_availabilitygroupnameip, :array_matching => :all) do - def mof_type; 'string[]' end - def mof_is_embedded?; false end - desc "AvailabilityGroupNameIP - List of IP addresses associated with listener." - validate do |value| - unless value.kind_of?(Array) || value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string or an array of strings") - end - end - munge do |value| - Array(value) - end - end - - # Name: AvailabilityGroupSubMask - # Type: string[] + # Name: MailServerName + # Type: string # IsMandatory: False # Values: None - newparam(:dsc_availabilitygroupsubmask, :array_matching => :all) do - def mof_type; 'string[]' end + newparam(:dsc_mailservername) do + def mof_type; 'string' end def mof_is_embedded?; false end - desc "AvailabilityGroupSubMask - Network subnetmask for listener." + desc "MailServerName - The fully qualified domain name of the mail server name to which e-mail are sent." validate do |value| - unless value.kind_of?(Array) || value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string or an array of strings") + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") end end - munge do |value| - Array(value) - end end - # Name: AvailabilityGroupPort - # Type: uint32 + # Name: ProfileName + # Type: string # IsMandatory: False # Values: None - newparam(:dsc_availabilitygroupport) do - def mof_type; 'uint32' end + newparam(:dsc_profilename) do + def mof_type; 'string' end def mof_is_embedded?; false end - desc "AvailabilityGroupPort - Port availability group should listen on." + desc "ProfileName - The profile name of the Database Mail." validate do |value| - unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) - fail("Invalid value #{value}. Should be a unsigned Integer") + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") end end - munge do |value| - PuppetX::Dsc::TypeHelpers.munge_integer(value) - end end - # Name: ReadableSecondary + # Name: Ensure # Type: string # IsMandatory: False - # Values: ["None", "ReadOnly", "ReadIntent"] - newparam(:dsc_readablesecondary) do + # Values: ["Present", "Absent"] + newparam(:dsc_ensure) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "ReadableSecondary - Mode secondaries should operate under (None, ReadOnly, ReadIntent). Valid values are None, ReadOnly, ReadIntent." + desc "Ensure - Specifies the desired state of the Database Mail. When set to 'Present', the Database Mail will be created. When set to 'Absent', the Database Mail will be removed. Default value is 'Present'. Valid values are Present, Absent." validate do |value| + resource[:ensure] = value.downcase unless value.kind_of?(String) fail("Invalid value '#{value}'. Should be a string") end - unless ['None', 'none', 'ReadOnly', 'readonly', 'ReadIntent', 'readintent'].include?(value) - fail("Invalid value '#{value}'. Valid values are None, ReadOnly, ReadIntent") + unless ['Present', 'present', 'Absent', 'absent'].include?(value) + fail("Invalid value '#{value}'. Valid values are Present, Absent") end end end - # Name: AutoBackupPreference + # Name: ServerName # Type: string # IsMandatory: False - # Values: ["Primary", "Secondary"] - newparam(:dsc_autobackuppreference) do + # Values: None + newparam(:dsc_servername) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "AutoBackupPreference - Where backups should be backed up from (Primary, Secondary). Valid values are Primary, Secondary." + desc "ServerName - The hostname of the SQL Server to be configured. Defaults to $env:COMPUTERNAME." validate do |value| unless value.kind_of?(String) fail("Invalid value '#{value}'. Should be a string") end - unless ['Primary', 'primary', 'Secondary', 'secondary'].include?(value) - fail("Invalid value '#{value}'. Valid values are Primary, Secondary") - end end end - # Name: BackupPriority - # Type: uint32 + # Name: DisplayName + # Type: string # IsMandatory: False # Values: None - newparam(:dsc_backuppriority) do - def mof_type; 'uint32' end + newparam(:dsc_displayname) do + def mof_type; 'string' end def mof_is_embedded?; false end - desc "BackupPriority - The percentage weight for backup prority (default 50)." + desc "DisplayName - The display name of the outgoing mail server. Default value is the same value assigned to parameter MailServerName." validate do |value| - unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) - fail("Invalid value #{value}. Should be a unsigned Integer") + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") end end - munge do |value| - PuppetX::Dsc::TypeHelpers.munge_integer(value) - end end - # Name: EndPointPort - # Type: uint32 + # Name: ReplyToAddress + # Type: string # IsMandatory: False # Values: None - newparam(:dsc_endpointport) do - def mof_type; 'uint32' end + newparam(:dsc_replytoaddress) do + def mof_type; 'string' end def mof_is_embedded?; false end - desc "EndPointPort - he TCP port for the SQL AG Endpoint (default 5022)." + desc "ReplyToAddress - The e-mail address to which the receiver of e-mails will reply to. Default value is the same e-mail address assigned to parameter EmailAddress." validate do |value| - unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) - fail("Invalid value #{value}. Should be a unsigned Integer") + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") end end - munge do |value| - PuppetX::Dsc::TypeHelpers.munge_integer(value) - end end - # Name: SQLServer + # Name: Description # Type: string # IsMandatory: False # Values: None - newparam(:dsc_sqlserver) do + newparam(:dsc_description) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "SQLServer - The SQL Server for the database." + desc "Description - The description of the Database Mail." validate do |value| unless value.kind_of?(String) fail("Invalid value '#{value}'. Should be a string") @@ -248,34 +212,39 @@ def mof_is_embedded?; false end end end - # Name: SQLInstanceName + # Name: LoggingLevel # Type: string # IsMandatory: False - # Values: None - newparam(:dsc_sqlinstancename) do + # Values: ["Normal", "Extended", "Verbose"] + newparam(:dsc_logginglevel) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "SQLInstanceName - The SQL instance for the database." + desc "LoggingLevel - The logging level that the Database Mail will use. If not specified the default logging level is 'Extended'. Valid values are Normal, Extended, Verbose." validate do |value| unless value.kind_of?(String) fail("Invalid value '#{value}'. Should be a string") end + unless ['Normal', 'normal', 'Extended', 'extended', 'Verbose', 'verbose'].include?(value) + fail("Invalid value '#{value}'. Valid values are Normal, Extended, Verbose") + end end end - # Name: SetupCredential - # Type: MSFT_Credential + # Name: TcpPort + # Type: uint16 # IsMandatory: False # Values: None - newparam(:dsc_setupcredential) do - def mof_type; 'MSFT_Credential' end - def mof_is_embedded?; true end - desc "SetupCredential - Credential to be used to Grant Permissions on SQL Server, set this to $null to use Windows Authentication." + newparam(:dsc_tcpport) do + def mof_type; 'uint16' end + def mof_is_embedded?; false end + desc "TcpPort - The TCP port used for communication. Default value is port 25." validate do |value| - unless value.kind_of?(Hash) - fail("Invalid value '#{value}'. Should be a hash") + unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) + fail("Invalid value #{value}. Should be a unsigned Integer") end - PuppetX::Dsc::TypeHelpers.validate_MSFT_Credential("SetupCredential", value) + end + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_integer(value) end end @@ -286,7 +255,7 @@ def builddepends end end -Puppet::Type.type(:dsc_xsqlaogroupensure).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do +Puppet::Type.type(:dsc_sqlserverdatabasemail).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) defaultfor :operatingsystem => :windows diff --git a/lib/puppet/type/dsc_xsqlserverendpoint.rb b/lib/puppet/type/dsc_sqlserverendpoint.rb similarity index 83% rename from lib/puppet/type/dsc_xsqlserverendpoint.rb rename to lib/puppet/type/dsc_sqlserverendpoint.rb index 235a56646..f3cced268 100644 --- a/lib/puppet/type/dsc_xsqlserverendpoint.rb +++ b/lib/puppet/type/dsc_sqlserverendpoint.rb @@ -1,14 +1,14 @@ require 'pathname' -Puppet::Type.newtype(:dsc_xsqlserverendpoint) do +Puppet::Type.newtype(:dsc_sqlserverendpoint) do require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' @doc = %q{ - The DSC xSQLServerEndpoint resource type. + The DSC SqlServerEndpoint resource type. Automatically generated from - 'xSQLServer/DSCResources/MSFT_xSQLServerEndpoint/MSFT_xSQLServerEndpoint.schema.mof' + 'SqlServerDsc/DSCResources/MSFT_SqlServerEndpoint/MSFT_SqlServerEndpoint.schema.mof' To learn more about PowerShell Desired State Configuration, please visit https://technet.microsoft.com/en-us/library/dn249912.aspx. @@ -22,13 +22,13 @@ validate do fail('dsc_endpointname is a required attribute') if self[:dsc_endpointname].nil? - fail('dsc_sqlinstancename is a required attribute') if self[:dsc_sqlinstancename].nil? + fail('dsc_instancename is a required attribute') if self[:dsc_instancename].nil? end - def dscmeta_resource_friendly_name; 'xSQLServerEndpoint' end - def dscmeta_resource_name; 'MSFT_xSQLServerEndpoint' end - def dscmeta_module_name; 'xSQLServer' end - def dscmeta_module_version; '7.0.0.0' end + def dscmeta_resource_friendly_name; 'SqlServerEndpoint' end + def dscmeta_resource_name; 'MSFT_SqlServerEndpoint' end + def dscmeta_module_name; 'SqlServerDsc' end + def dscmeta_module_version; '11.0.0.0' end newparam(:name, :namevar => true ) do end @@ -109,14 +109,14 @@ def mof_is_embedded?; false end end end - # Name: SQLServer + # Name: ServerName # Type: string # IsMandatory: False # Values: None - newparam(:dsc_sqlserver) do + newparam(:dsc_servername) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "SQLServer - The host name of the SQL Server to be configured. Default value is $env:COMPUTERNAME." + desc "ServerName - The host name of the SQL Server to be configured. Default value is $env:COMPUTERNAME." validate do |value| unless value.kind_of?(String) fail("Invalid value '#{value}'. Should be a string") @@ -124,14 +124,14 @@ def mof_is_embedded?; false end end end - # Name: SQLInstanceName + # Name: InstanceName # Type: string # IsMandatory: True # Values: None - newparam(:dsc_sqlinstancename) do + newparam(:dsc_instancename) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "SQLInstanceName - The name of the SQL instance to be configured." + desc "InstanceName - The name of the SQL instance to be configured." isrequired validate do |value| unless value.kind_of?(String) @@ -162,7 +162,7 @@ def builddepends end end -Puppet::Type.type(:dsc_xsqlserverendpoint).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do +Puppet::Type.type(:dsc_sqlserverendpoint).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) defaultfor :operatingsystem => :windows diff --git a/lib/puppet/type/dsc_xsqlserverendpointpermission.rb b/lib/puppet/type/dsc_sqlserverendpointpermission.rb similarity index 86% rename from lib/puppet/type/dsc_xsqlserverendpointpermission.rb rename to lib/puppet/type/dsc_sqlserverendpointpermission.rb index 1ce536588..3e4ea2c78 100644 --- a/lib/puppet/type/dsc_xsqlserverendpointpermission.rb +++ b/lib/puppet/type/dsc_sqlserverendpointpermission.rb @@ -1,14 +1,14 @@ require 'pathname' -Puppet::Type.newtype(:dsc_xsqlserverendpointpermission) do +Puppet::Type.newtype(:dsc_sqlserverendpointpermission) do require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' @doc = %q{ - The DSC xSQLServerEndpointPermission resource type. + The DSC SqlServerEndpointPermission resource type. Automatically generated from - 'xSQLServer/DSCResources/MSFT_xSQLServerEndpointPermission/MSFT_xSQLServerEndpointPermission.schema.mof' + 'SqlServerDsc/DSCResources/MSFT_SqlServerEndpointPermission/MSFT_SqlServerEndpointPermission.schema.mof' To learn more about PowerShell Desired State Configuration, please visit https://technet.microsoft.com/en-us/library/dn249912.aspx. @@ -25,10 +25,10 @@ fail('dsc_principal is a required attribute') if self[:dsc_principal].nil? end - def dscmeta_resource_friendly_name; 'xSQLServerEndpointPermission' end - def dscmeta_resource_name; 'MSFT_xSQLServerEndpointPermission' end - def dscmeta_module_name; 'xSQLServer' end - def dscmeta_module_version; '7.0.0.0' end + def dscmeta_resource_friendly_name; 'SqlServerEndpointPermission' end + def dscmeta_resource_name; 'MSFT_SqlServerEndpointPermission' end + def dscmeta_module_name; 'SqlServerDsc' end + def dscmeta_module_version; '11.0.0.0' end newparam(:name, :namevar => true ) do end @@ -72,14 +72,14 @@ def mof_is_embedded?; false end end end - # Name: NodeName + # Name: ServerName # Type: string # IsMandatory: False # Values: None - newparam(:dsc_nodename) do + newparam(:dsc_servername) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "NodeName - The host name of the SQL Server to be configured." + desc "ServerName - The host name of the SQL Server to be configured." validate do |value| unless value.kind_of?(String) fail("Invalid value '#{value}'. Should be a string") @@ -162,7 +162,7 @@ def builddepends end end -Puppet::Type.type(:dsc_xsqlserverendpointpermission).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do +Puppet::Type.type(:dsc_sqlserverendpointpermission).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) defaultfor :operatingsystem => :windows diff --git a/lib/puppet/type/dsc_xsqlserverendpointstate.rb b/lib/puppet/type/dsc_sqlserverendpointstate.rb similarity index 83% rename from lib/puppet/type/dsc_xsqlserverendpointstate.rb rename to lib/puppet/type/dsc_sqlserverendpointstate.rb index 54bfd5527..16e77693d 100644 --- a/lib/puppet/type/dsc_xsqlserverendpointstate.rb +++ b/lib/puppet/type/dsc_sqlserverendpointstate.rb @@ -1,14 +1,14 @@ require 'pathname' -Puppet::Type.newtype(:dsc_xsqlserverendpointstate) do +Puppet::Type.newtype(:dsc_sqlserverendpointstate) do require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' @doc = %q{ - The DSC xSQLServerEndpointState resource type. + The DSC SqlServerEndpointState resource type. Automatically generated from - 'xSQLServer/DSCResources/MSFT_xSQLServerEndpointState/MSFT_xSQLServerEndpointState.schema.mof' + 'SqlServerDsc/DSCResources/MSFT_SqlServerEndpointState/MSFT_SqlServerEndpointState.schema.mof' To learn more about PowerShell Desired State Configuration, please visit https://technet.microsoft.com/en-us/library/dn249912.aspx. @@ -25,10 +25,10 @@ fail('dsc_name is a required attribute') if self[:dsc_name].nil? end - def dscmeta_resource_friendly_name; 'xSQLServerEndpointState' end - def dscmeta_resource_name; 'MSFT_xSQLServerEndpointState' end - def dscmeta_module_name; 'xSQLServer' end - def dscmeta_module_version; '7.0.0.0' end + def dscmeta_resource_friendly_name; 'SqlServerEndpointState' end + def dscmeta_resource_name; 'MSFT_SqlServerEndpointState' end + def dscmeta_module_name; 'SqlServerDsc' end + def dscmeta_module_version; '11.0.0.0' end newparam(:name, :namevar => true ) do end @@ -71,14 +71,14 @@ def mof_is_embedded?; false end end end - # Name: NodeName + # Name: ServerName # Type: string # IsMandatory: False # Values: None - newparam(:dsc_nodename) do + newparam(:dsc_servername) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "NodeName - The host name of the SQL Server to be configured. Default value is $env:COMPUTERNAME." + desc "ServerName - The host name of the SQL Server to be configured. Default value is $env:COMPUTERNAME." validate do |value| unless value.kind_of?(String) fail("Invalid value '#{value}'. Should be a string") @@ -127,7 +127,7 @@ def builddepends end end -Puppet::Type.type(:dsc_xsqlserverendpointstate).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do +Puppet::Type.type(:dsc_sqlserverendpointstate).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) defaultfor :operatingsystem => :windows diff --git a/lib/puppet/type/dsc_xsqlserverlogin.rb b/lib/puppet/type/dsc_sqlserverlogin.rb similarity index 83% rename from lib/puppet/type/dsc_xsqlserverlogin.rb rename to lib/puppet/type/dsc_sqlserverlogin.rb index 71f2c3e27..5de235ecb 100644 --- a/lib/puppet/type/dsc_xsqlserverlogin.rb +++ b/lib/puppet/type/dsc_sqlserverlogin.rb @@ -1,14 +1,14 @@ require 'pathname' -Puppet::Type.newtype(:dsc_xsqlserverlogin) do +Puppet::Type.newtype(:dsc_sqlserverlogin) do require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' @doc = %q{ - The DSC xSQLServerLogin resource type. + The DSC SqlServerLogin resource type. Automatically generated from - 'xSQLServer/DSCResources/MSFT_xSQLServerLogin/MSFT_xSQLServerLogin.schema.mof' + 'SqlServerDsc/DSCResources/MSFT_SqlServerLogin/MSFT_SqlServerLogin.schema.mof' To learn more about PowerShell Desired State Configuration, please visit https://technet.microsoft.com/en-us/library/dn249912.aspx. @@ -22,14 +22,14 @@ validate do fail('dsc_name is a required attribute') if self[:dsc_name].nil? - fail('dsc_sqlserver is a required attribute') if self[:dsc_sqlserver].nil? - fail('dsc_sqlinstancename is a required attribute') if self[:dsc_sqlinstancename].nil? + fail('dsc_servername is a required attribute') if self[:dsc_servername].nil? + fail('dsc_instancename is a required attribute') if self[:dsc_instancename].nil? end - def dscmeta_resource_friendly_name; 'xSQLServerLogin' end - def dscmeta_resource_name; 'MSFT_xSQLServerLogin' end - def dscmeta_module_name; 'xSQLServer' end - def dscmeta_module_version; '7.0.0.0' end + def dscmeta_resource_friendly_name; 'SqlServerLogin' end + def dscmeta_resource_name; 'MSFT_SqlServerLogin' end + def dscmeta_module_name; 'SqlServerDsc' end + def dscmeta_module_version; '11.0.0.0' end newparam(:name, :namevar => true ) do end @@ -110,14 +110,14 @@ def mof_is_embedded?; false end end end - # Name: SQLServer + # Name: ServerName # Type: string # IsMandatory: True # Values: None - newparam(:dsc_sqlserver) do + newparam(:dsc_servername) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "SQLServer - The hostname of the SQL Server to be configured." + desc "ServerName - The hostname of the SQL Server to be configured." isrequired validate do |value| unless value.kind_of?(String) @@ -126,14 +126,14 @@ def mof_is_embedded?; false end end end - # Name: SQLInstanceName + # Name: InstanceName # Type: string # IsMandatory: True # Values: None - newparam(:dsc_sqlinstancename) do + newparam(:dsc_instancename) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "SQLInstanceName - Name of the SQL instance to be configured." + desc "InstanceName - Name of the SQL instance to be configured." isrequired validate do |value| unless value.kind_of?(String) @@ -206,6 +206,22 @@ def mof_is_embedded?; false end end end + # Name: Disabled + # Type: boolean + # IsMandatory: False + # Values: None + newparam(:dsc_disabled) do + def mof_type; 'boolean' end + def mof_is_embedded?; false end + desc "Disabled - Specifies if the login is disabled. Default is $false." + validate do |value| + end + newvalues(true, false) + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_boolean(value.to_s) + end + end + def builddepends pending_relations = super() @@ -213,7 +229,7 @@ def builddepends end end -Puppet::Type.type(:dsc_xsqlserverlogin).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do +Puppet::Type.type(:dsc_sqlserverlogin).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) defaultfor :operatingsystem => :windows diff --git a/lib/puppet/type/dsc_sqlservermaxdop.rb b/lib/puppet/type/dsc_sqlservermaxdop.rb new file mode 100644 index 000000000..f46acc1cf --- /dev/null +++ b/lib/puppet/type/dsc_sqlservermaxdop.rb @@ -0,0 +1,186 @@ +require 'pathname' + +Puppet::Type.newtype(:dsc_sqlservermaxdop) do + require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' + require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' + + + @doc = %q{ + The DSC SqlServerMaxDop resource type. + Automatically generated from + 'SqlServerDsc/DSCResources/MSFT_SqlServerMaxDop/MSFT_SqlServerMaxDop.schema.mof' + + To learn more about PowerShell Desired State Configuration, please + visit https://technet.microsoft.com/en-us/library/dn249912.aspx. + + For more information about built-in DSC Resources, please visit + https://technet.microsoft.com/en-us/library/dn249921.aspx. + + For more information about xDsc Resources, please visit + https://github.com/PowerShell/DscResources. + } + + validate do + fail('dsc_instancename is a required attribute') if self[:dsc_instancename].nil? + end + + def dscmeta_resource_friendly_name; 'SqlServerMaxDop' end + def dscmeta_resource_name; 'MSFT_SqlServerMaxDop' end + def dscmeta_module_name; 'SqlServerDsc' end + def dscmeta_module_version; '11.0.0.0' end + + newparam(:name, :namevar => true ) do + end + + ensurable do + newvalue(:exists?) { provider.exists? } + newvalue(:present) { provider.create } + newvalue(:absent) { provider.destroy } + defaultto { :present } + end + + # Name: PsDscRunAsCredential + # Type: MSFT_Credential + # IsMandatory: False + # Values: None + newparam(:dsc_psdscrunascredential) do + def mof_type; 'MSFT_Credential' end + def mof_is_embedded?; true end + desc "PsDscRunAsCredential" + validate do |value| + unless value.kind_of?(Hash) + fail("Invalid value '#{value}'. Should be a hash") + end + PuppetX::Dsc::TypeHelpers.validate_MSFT_Credential("Credential", value) + end + end + + # Name: Ensure + # Type: string + # IsMandatory: False + # Values: ["Present", "Absent"] + newparam(:dsc_ensure) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Ensure - When set to 'Present' then max degree of parallelism will be set to either the value in parameter MaxDop or dynamically configured when parameter DynamicAlloc is set to $true. When set to 'Absent' max degree of parallelism will be set to 0 which means no limit in number of processors used in parallel plan execution. Valid values are Present, Absent." + validate do |value| + resource[:ensure] = value.downcase + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + unless ['Present', 'present', 'Absent', 'absent'].include?(value) + fail("Invalid value '#{value}'. Valid values are Present, Absent") + end + end + end + + # Name: DynamicAlloc + # Type: boolean + # IsMandatory: False + # Values: None + newparam(:dsc_dynamicalloc) do + def mof_type; 'boolean' end + def mof_is_embedded?; false end + desc "DynamicAlloc - If set to $true then max degree of parallelism will be dynamically configured. When this is set parameter is set to $true, the parameter MaxDop must be set to $null or not be configured." + validate do |value| + end + newvalues(true, false) + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_boolean(value.to_s) + end + end + + # Name: MaxDop + # Type: sint32 + # IsMandatory: False + # Values: None + newparam(:dsc_maxdop) do + def mof_type; 'sint32' end + def mof_is_embedded?; false end + desc "MaxDop - A numeric value to limit the number of processors used in parallel plan execution." + validate do |value| + unless value.kind_of?(Numeric) || value.to_i.to_s == value + fail("Invalid value #{value}. Should be a signed Integer") + end + end + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_integer(value) + end + end + + # Name: ServerName + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_servername) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "ServerName - The host name of the SQL Server to be configured. Default value is $env:COMPUTERNAME." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: InstanceName + # Type: string + # IsMandatory: True + # Values: None + newparam(:dsc_instancename) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "InstanceName - The name of the SQL instance to be configured." + isrequired + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: ProcessOnlyOnActiveNode + # Type: boolean + # IsMandatory: False + # Values: None + newparam(:dsc_processonlyonactivenode) do + def mof_type; 'boolean' end + def mof_is_embedded?; false end + desc "ProcessOnlyOnActiveNode - Specifies that the resource will only determine if a change is needed if the target node is the active host of the SQL Server instance." + validate do |value| + end + newvalues(true, false) + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_boolean(value.to_s) + end + end + + # Name: IsActiveNode + # Type: boolean + # IsMandatory: False + # Values: None + newparam(:dsc_isactivenode) do + def mof_type; 'boolean' end + def mof_is_embedded?; false end + desc "IsActiveNode - Determines if the current node is actively hosting the SQL Server instance." + validate do |value| + end + newvalues(true, false) + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_boolean(value.to_s) + end + end + + + def builddepends + pending_relations = super() + PuppetX::Dsc::TypeHelpers.ensure_reboot_relationship(self, pending_relations) + end +end + +Puppet::Type.type(:dsc_sqlservermaxdop).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do + confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) + defaultfor :operatingsystem => :windows + + mk_resource_methods +end diff --git a/lib/puppet/type/dsc_xsqlservermemory.rb b/lib/puppet/type/dsc_sqlservermemory.rb similarity index 72% rename from lib/puppet/type/dsc_xsqlservermemory.rb rename to lib/puppet/type/dsc_sqlservermemory.rb index edb1e8127..e709e7d49 100644 --- a/lib/puppet/type/dsc_xsqlservermemory.rb +++ b/lib/puppet/type/dsc_sqlservermemory.rb @@ -1,14 +1,14 @@ require 'pathname' -Puppet::Type.newtype(:dsc_xsqlservermemory) do +Puppet::Type.newtype(:dsc_sqlservermemory) do require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' @doc = %q{ - The DSC xSQLServerMemory resource type. + The DSC SqlServerMemory resource type. Automatically generated from - 'xSQLServer/DSCResources/MSFT_xSQLServerMemory/MSFT_xSQLServerMemory.schema.mof' + 'SqlServerDsc/DSCResources/MSFT_SqlServerMemory/MSFT_SqlServerMemory.schema.mof' To learn more about PowerShell Desired State Configuration, please visit https://technet.microsoft.com/en-us/library/dn249912.aspx. @@ -21,13 +21,13 @@ } validate do - fail('dsc_sqlinstancename is a required attribute') if self[:dsc_sqlinstancename].nil? + fail('dsc_instancename is a required attribute') if self[:dsc_instancename].nil? end - def dscmeta_resource_friendly_name; 'xSQLServerMemory' end - def dscmeta_resource_name; 'MSFT_xSQLServerMemory' end - def dscmeta_module_name; 'xSQLServer' end - def dscmeta_module_version; '7.0.0.0' end + def dscmeta_resource_friendly_name; 'SqlServerMemory' end + def dscmeta_resource_name; 'MSFT_SqlServerMemory' end + def dscmeta_module_name; 'SqlServerDsc' end + def dscmeta_module_version; '11.0.0.0' end newparam(:name, :namevar => true ) do end @@ -55,14 +55,14 @@ def mof_is_embedded?; true end end end - # Name: SQLInstanceName + # Name: InstanceName # Type: string # IsMandatory: True # Values: None - newparam(:dsc_sqlinstancename) do + newparam(:dsc_instancename) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "SQLInstanceName - The name of the SQL instance to be configured." + desc "InstanceName - The name of the SQL instance to be configured." isrequired validate do |value| unless value.kind_of?(String) @@ -71,14 +71,14 @@ def mof_is_embedded?; false end end end - # Name: SQLServer + # Name: ServerName # Type: string # IsMandatory: False # Values: None - newparam(:dsc_sqlserver) do + newparam(:dsc_servername) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "SQLServer - The host name of the SQL Server to be configured. Default value is $env:COMPUTERNAME." + desc "ServerName - The host name of the SQL Server to be configured. Default value is $env:COMPUTERNAME." validate do |value| unless value.kind_of?(String) fail("Invalid value '#{value}'. Should be a string") @@ -157,6 +157,38 @@ def mof_is_embedded?; false end end end + # Name: ProcessOnlyOnActiveNode + # Type: boolean + # IsMandatory: False + # Values: None + newparam(:dsc_processonlyonactivenode) do + def mof_type; 'boolean' end + def mof_is_embedded?; false end + desc "ProcessOnlyOnActiveNode - Specifies that the resource will only determine if a change is needed if the target node is the active host of the SQL Server instance." + validate do |value| + end + newvalues(true, false) + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_boolean(value.to_s) + end + end + + # Name: IsActiveNode + # Type: boolean + # IsMandatory: False + # Values: None + newparam(:dsc_isactivenode) do + def mof_type; 'boolean' end + def mof_is_embedded?; false end + desc "IsActiveNode - Determines if the current node is actively hosting the SQL Server instance." + validate do |value| + end + newvalues(true, false) + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_boolean(value.to_s) + end + end + def builddepends pending_relations = super() @@ -164,7 +196,7 @@ def builddepends end end -Puppet::Type.type(:dsc_xsqlservermemory).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do +Puppet::Type.type(:dsc_sqlservermemory).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) defaultfor :operatingsystem => :windows diff --git a/lib/puppet/type/dsc_sqlservernetwork.rb b/lib/puppet/type/dsc_sqlservernetwork.rb new file mode 100644 index 000000000..26a86561e --- /dev/null +++ b/lib/puppet/type/dsc_sqlservernetwork.rb @@ -0,0 +1,199 @@ +require 'pathname' + +Puppet::Type.newtype(:dsc_sqlservernetwork) do + require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' + require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' + + + @doc = %q{ + The DSC SqlServerNetwork resource type. + Automatically generated from + 'SqlServerDsc/DSCResources/MSFT_SqlServerNetwork/MSFT_SqlServerNetwork.schema.mof' + + To learn more about PowerShell Desired State Configuration, please + visit https://technet.microsoft.com/en-us/library/dn249912.aspx. + + For more information about built-in DSC Resources, please visit + https://technet.microsoft.com/en-us/library/dn249921.aspx. + + For more information about xDsc Resources, please visit + https://github.com/PowerShell/DscResources. + } + + validate do + fail('dsc_instancename is a required attribute') if self[:dsc_instancename].nil? + end + + def dscmeta_resource_friendly_name; 'SqlServerNetwork' end + def dscmeta_resource_name; 'MSFT_SqlServerNetwork' end + def dscmeta_module_name; 'SqlServerDsc' end + def dscmeta_module_version; '11.0.0.0' end + + newparam(:name, :namevar => true ) do + end + + ensurable do + newvalue(:exists?) { provider.exists? } + newvalue(:present) { provider.create } + defaultto { :present } + end + + # Name: PsDscRunAsCredential + # Type: MSFT_Credential + # IsMandatory: False + # Values: None + newparam(:dsc_psdscrunascredential) do + def mof_type; 'MSFT_Credential' end + def mof_is_embedded?; true end + desc "PsDscRunAsCredential" + validate do |value| + unless value.kind_of?(Hash) + fail("Invalid value '#{value}'. Should be a hash") + end + PuppetX::Dsc::TypeHelpers.validate_MSFT_Credential("Credential", value) + end + end + + # Name: InstanceName + # Type: string + # IsMandatory: True + # Values: None + newparam(:dsc_instancename) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "InstanceName - The name of the SQL instance to be configured." + isrequired + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: ProtocolName + # Type: string + # IsMandatory: False + # Values: ["Tcp"] + newparam(:dsc_protocolname) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "ProtocolName - The name of network protocol to be configured. Only tcp is currently supported. Valid values are Tcp." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + unless ['Tcp', 'tcp'].include?(value) + fail("Invalid value '#{value}'. Valid values are Tcp") + end + end + end + + # Name: ServerName + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_servername) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "ServerName - The host name of the SQL Server to be configured. Default value is $env:COMPUTERNAME." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: IsEnabled + # Type: boolean + # IsMandatory: False + # Values: None + newparam(:dsc_isenabled) do + def mof_type; 'boolean' end + def mof_is_embedded?; false end + desc "IsEnabled - Enables or disables the network protocol." + validate do |value| + end + newvalues(true, false) + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_boolean(value.to_s) + end + end + + # Name: TcpDynamicPort + # Type: boolean + # IsMandatory: False + # Values: None + newparam(:dsc_tcpdynamicport) do + def mof_type; 'boolean' end + def mof_is_embedded?; false end + desc "TcpDynamicPort - Specifies whether the SQL Server instance should use a dynamic port. Value cannot be set to 'True' if TcpPort is set to a non-empty string." + validate do |value| + end + newvalues(true, false) + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_boolean(value.to_s) + end + end + + # Name: TcpPort + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_tcpport) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "TcpPort - The TCP port(s) that SQL Server should be listening on. If the IP address should listen on more than one port, list all ports separated with a comma ('1433,1500,1501'). To use this parameter set TcpDynamicPorts to 'False'." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: RestartService + # Type: boolean + # IsMandatory: False + # Values: None + newparam(:dsc_restartservice) do + def mof_type; 'boolean' end + def mof_is_embedded?; false end + desc "RestartService - If set to $true then SQL Server and dependent services will be restarted if a change to the configuration is made. The default value is $false." + validate do |value| + end + newvalues(true, false) + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_boolean(value.to_s) + end + end + + # Name: RestartTimeout + # Type: uint16 + # IsMandatory: False + # Values: None + newparam(:dsc_restarttimeout) do + def mof_type; 'uint16' end + def mof_is_embedded?; false end + desc "RestartTimeout - Timeout value for restarting the SQL Server services. The default value is 120 seconds." + validate do |value| + unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) + fail("Invalid value #{value}. Should be a unsigned Integer") + end + end + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_integer(value) + end + end + + + def builddepends + pending_relations = super() + PuppetX::Dsc::TypeHelpers.ensure_reboot_relationship(self, pending_relations) + end +end + +Puppet::Type.type(:dsc_sqlservernetwork).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do + confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) + defaultfor :operatingsystem => :windows + + mk_resource_methods +end diff --git a/lib/puppet/type/dsc_xsqlserverpermission.rb b/lib/puppet/type/dsc_sqlserverpermission.rb similarity index 68% rename from lib/puppet/type/dsc_xsqlserverpermission.rb rename to lib/puppet/type/dsc_sqlserverpermission.rb index 1f09afcaa..7bd3704de 100644 --- a/lib/puppet/type/dsc_xsqlserverpermission.rb +++ b/lib/puppet/type/dsc_sqlserverpermission.rb @@ -1,14 +1,14 @@ require 'pathname' -Puppet::Type.newtype(:dsc_xsqlserverpermission) do +Puppet::Type.newtype(:dsc_sqlserverpermission) do require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' @doc = %q{ - The DSC xSQLServerPermission resource type. + The DSC SqlServerPermission resource type. Automatically generated from - 'xSQLServer/DSCResources/MSFT_xSQLServerPermission/MSFT_xSQLServerPermission.schema.mof' + 'SqlServerDsc/DSCResources/MSFT_SqlServerPermission/MSFT_SqlServerPermission.schema.mof' To learn more about PowerShell Desired State Configuration, please visit https://technet.microsoft.com/en-us/library/dn249912.aspx. @@ -22,12 +22,13 @@ validate do fail('dsc_instancename is a required attribute') if self[:dsc_instancename].nil? + fail('dsc_principal is a required attribute') if self[:dsc_principal].nil? end - def dscmeta_resource_friendly_name; 'xSQLServerPermission' end - def dscmeta_resource_name; 'MSFT_xSQLServerPermission' end - def dscmeta_module_name; 'xSQLServer' end - def dscmeta_module_version; '7.0.0.0' end + def dscmeta_resource_friendly_name; 'SqlServerPermission' end + def dscmeta_resource_name; 'MSFT_SqlServerPermission' end + def dscmeta_module_name; 'SqlServerDsc' end + def dscmeta_module_version; '11.0.0.0' end newparam(:name, :namevar => true ) do end @@ -62,7 +63,7 @@ def mof_is_embedded?; true end newparam(:dsc_instancename) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "InstanceName - The SQL Server instance name." + desc "InstanceName - The name of the SQL instance to be configured." isrequired validate do |value| unless value.kind_of?(String) @@ -71,14 +72,14 @@ def mof_is_embedded?; false end end end - # Name: NodeName + # Name: ServerName # Type: string # IsMandatory: False # Values: None - newparam(:dsc_nodename) do + newparam(:dsc_servername) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "NodeName - The host name or FQDN." + desc "ServerName - The host name of the SQL Server to be configured. Default value is $env:COMPUTERNAME." validate do |value| unless value.kind_of?(String) fail("Invalid value '#{value}'. Should be a string") @@ -93,7 +94,7 @@ def mof_is_embedded?; false end newparam(:dsc_ensure) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "Ensure - If the permission should be present or absent. Valid values are Present, Absent." + desc "Ensure - If the permission should be present or absent. Default value is 'Present'. Valid values are Present, Absent." validate do |value| resource[:ensure] = value.downcase unless value.kind_of?(String) @@ -107,12 +108,13 @@ def mof_is_embedded?; false end # Name: Principal # Type: string - # IsMandatory: False + # IsMandatory: True # Values: None newparam(:dsc_principal) do def mof_type; 'string' end def mof_is_embedded?; false end desc "Principal - The login to which permission will be set." + isrequired validate do |value| unless value.kind_of?(String) fail("Invalid value '#{value}'. Should be a string") @@ -123,23 +125,23 @@ def mof_is_embedded?; false end # Name: Permission # Type: string[] # IsMandatory: False - # Values: ["AlterAnyAvailabilityGroup", "ViewServerState", "AlterAnyEndPoint"] + # Values: ["ConnectSql", "AlterAnyAvailabilityGroup", "ViewServerState", "AlterAnyEndPoint"] newparam(:dsc_permission, :array_matching => :all) do def mof_type; 'string[]' end def mof_is_embedded?; false end - desc "Permission - The permission to set for the login. Valid values are AlterAnyAvailabilityGroup, ViewServerState, AlterAnyEndPoint." + desc "Permission - The permission to set for the login. Valid values are ConnectSql, AlterAnyAvailabilityGroup, ViewServerState or AlterAnyEndPoint. Valid values are ConnectSql, AlterAnyAvailabilityGroup, ViewServerState, AlterAnyEndPoint." validate do |value| unless value.kind_of?(Array) || value.kind_of?(String) fail("Invalid value '#{value}'. Should be a string or an array of strings") end if value.kind_of?(Array) - unless (['AlterAnyAvailabilityGroup', 'alteranyavailabilitygroup', 'ViewServerState', 'viewserverstate', 'AlterAnyEndPoint', 'alteranyendpoint'] & value).count == value.count - fail("Invalid value #{value}. Valid values are AlterAnyAvailabilityGroup, ViewServerState, AlterAnyEndPoint") + unless (['ConnectSql', 'connectsql', 'AlterAnyAvailabilityGroup', 'alteranyavailabilitygroup', 'ViewServerState', 'viewserverstate', 'AlterAnyEndPoint', 'alteranyendpoint'] & value).count == value.count + fail("Invalid value #{value}. Valid values are ConnectSql, AlterAnyAvailabilityGroup, ViewServerState, AlterAnyEndPoint") end end if value.kind_of?(String) - unless ['AlterAnyAvailabilityGroup', 'alteranyavailabilitygroup', 'ViewServerState', 'viewserverstate', 'AlterAnyEndPoint', 'alteranyendpoint'].include?(value) - fail("Invalid value #{value}. Valid values are AlterAnyAvailabilityGroup, ViewServerState, AlterAnyEndPoint") + unless ['ConnectSql', 'connectsql', 'AlterAnyAvailabilityGroup', 'alteranyavailabilitygroup', 'ViewServerState', 'viewserverstate', 'AlterAnyEndPoint', 'alteranyendpoint'].include?(value) + fail("Invalid value #{value}. Valid values are ConnectSql, AlterAnyAvailabilityGroup, ViewServerState, AlterAnyEndPoint") end end end @@ -155,7 +157,7 @@ def builddepends end end -Puppet::Type.type(:dsc_xsqlserverpermission).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do +Puppet::Type.type(:dsc_sqlserverpermission).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) defaultfor :operatingsystem => :windows diff --git a/lib/puppet/type/dsc_xsqlserverreplication.rb b/lib/puppet/type/dsc_sqlserverreplication.rb similarity index 91% rename from lib/puppet/type/dsc_xsqlserverreplication.rb rename to lib/puppet/type/dsc_sqlserverreplication.rb index bca59fab1..7d69230af 100644 --- a/lib/puppet/type/dsc_xsqlserverreplication.rb +++ b/lib/puppet/type/dsc_sqlserverreplication.rb @@ -1,14 +1,14 @@ require 'pathname' -Puppet::Type.newtype(:dsc_xsqlserverreplication) do +Puppet::Type.newtype(:dsc_sqlserverreplication) do require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' @doc = %q{ - The DSC xSQLServerReplication resource type. + The DSC SqlServerReplication resource type. Automatically generated from - 'xSQLServer/DSCResources/MSFT_xSQLServerReplication/MSFT_xSQLServerReplication.schema.mof' + 'SqlServerDsc/DSCResources/MSFT_SqlServerReplication/MSFT_SqlServerReplication.schema.mof' To learn more about PowerShell Desired State Configuration, please visit https://technet.microsoft.com/en-us/library/dn249912.aspx. @@ -24,10 +24,10 @@ fail('dsc_instancename is a required attribute') if self[:dsc_instancename].nil? end - def dscmeta_resource_friendly_name; 'xSQLServerReplication' end - def dscmeta_resource_name; 'MSFT_xSQLServerReplication' end - def dscmeta_module_name; 'xSQLServer' end - def dscmeta_module_version; '7.0.0.0' end + def dscmeta_resource_friendly_name; 'SqlServerReplication' end + def dscmeta_resource_name; 'MSFT_SqlServerReplication' end + def dscmeta_module_name; 'SqlServerDsc' end + def dscmeta_module_version; '11.0.0.0' end newparam(:name, :namevar => true ) do end @@ -208,7 +208,7 @@ def builddepends end end -Puppet::Type.type(:dsc_xsqlserverreplication).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do +Puppet::Type.type(:dsc_sqlserverreplication).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) defaultfor :operatingsystem => :windows diff --git a/lib/puppet/type/dsc_xsqlserverrole.rb b/lib/puppet/type/dsc_sqlserverrole.rb similarity index 85% rename from lib/puppet/type/dsc_xsqlserverrole.rb rename to lib/puppet/type/dsc_sqlserverrole.rb index 90929fc89..ba641442b 100644 --- a/lib/puppet/type/dsc_xsqlserverrole.rb +++ b/lib/puppet/type/dsc_sqlserverrole.rb @@ -1,14 +1,14 @@ require 'pathname' -Puppet::Type.newtype(:dsc_xsqlserverrole) do +Puppet::Type.newtype(:dsc_sqlserverrole) do require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' @doc = %q{ - The DSC xSQLServerRole resource type. + The DSC SqlServerRole resource type. Automatically generated from - 'xSQLServer/DSCResources/MSFT_xSQLServerRole/MSFT_xSQLServerRole.schema.mof' + 'SqlServerDsc/DSCResources/MSFT_SqlServerRole/MSFT_SqlServerRole.schema.mof' To learn more about PowerShell Desired State Configuration, please visit https://technet.microsoft.com/en-us/library/dn249912.aspx. @@ -22,14 +22,14 @@ validate do fail('dsc_serverrolename is a required attribute') if self[:dsc_serverrolename].nil? - fail('dsc_sqlserver is a required attribute') if self[:dsc_sqlserver].nil? - fail('dsc_sqlinstancename is a required attribute') if self[:dsc_sqlinstancename].nil? + fail('dsc_servername is a required attribute') if self[:dsc_servername].nil? + fail('dsc_instancename is a required attribute') if self[:dsc_instancename].nil? end - def dscmeta_resource_friendly_name; 'xSQLServerRole' end - def dscmeta_resource_name; 'MSFT_xSQLServerRole' end - def dscmeta_module_name; 'xSQLServer' end - def dscmeta_module_version; '7.0.0.0' end + def dscmeta_resource_friendly_name; 'SqlServerRole' end + def dscmeta_resource_name; 'MSFT_SqlServerRole' end + def dscmeta_module_name; 'SqlServerDsc' end + def dscmeta_module_version; '11.0.0.0' end newparam(:name, :namevar => true ) do end @@ -73,14 +73,14 @@ def mof_is_embedded?; false end end end - # Name: SQLServer + # Name: ServerName # Type: string # IsMandatory: True # Values: None - newparam(:dsc_sqlserver) do + newparam(:dsc_servername) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "SQLServer - The host name of the SQL Server to be configured." + desc "ServerName - The host name of the SQL Server to be configured." isrequired validate do |value| unless value.kind_of?(String) @@ -89,14 +89,14 @@ def mof_is_embedded?; false end end end - # Name: SQLInstanceName + # Name: InstanceName # Type: string # IsMandatory: True # Values: None - newparam(:dsc_sqlinstancename) do + newparam(:dsc_instancename) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "SQLInstanceName - The name of the SQL instance to be configured." + desc "InstanceName - The name of the SQL instance to be configured." isrequired validate do |value| unless value.kind_of?(String) @@ -185,7 +185,7 @@ def builddepends end end -Puppet::Type.type(:dsc_xsqlserverrole).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do +Puppet::Type.type(:dsc_sqlserverrole).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) defaultfor :operatingsystem => :windows diff --git a/lib/puppet/type/dsc_sqlserviceaccount.rb b/lib/puppet/type/dsc_sqlserviceaccount.rb new file mode 100644 index 000000000..b23190160 --- /dev/null +++ b/lib/puppet/type/dsc_sqlserviceaccount.rb @@ -0,0 +1,185 @@ +require 'pathname' + +Puppet::Type.newtype(:dsc_sqlserviceaccount) do + require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' + require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' + + + @doc = %q{ + The DSC SqlServiceAccount resource type. + Automatically generated from + 'SqlServerDsc/DSCResources/MSFT_SqlServiceAccount/MSFT_SqlServiceAccount.schema.mof' + + To learn more about PowerShell Desired State Configuration, please + visit https://technet.microsoft.com/en-us/library/dn249912.aspx. + + For more information about built-in DSC Resources, please visit + https://technet.microsoft.com/en-us/library/dn249921.aspx. + + For more information about xDsc Resources, please visit + https://github.com/PowerShell/DscResources. + } + + validate do + fail('dsc_servername is a required attribute') if self[:dsc_servername].nil? + fail('dsc_instancename is a required attribute') if self[:dsc_instancename].nil? + fail('dsc_servicetype is a required attribute') if self[:dsc_servicetype].nil? + end + + def dscmeta_resource_friendly_name; 'SqlServiceAccount' end + def dscmeta_resource_name; 'MSFT_SqlServiceAccount' end + def dscmeta_module_name; 'SqlServerDsc' end + def dscmeta_module_version; '11.0.0.0' end + + newparam(:name, :namevar => true ) do + end + + ensurable do + newvalue(:exists?) { provider.exists? } + newvalue(:present) { provider.create } + defaultto { :present } + end + + # Name: PsDscRunAsCredential + # Type: MSFT_Credential + # IsMandatory: False + # Values: None + newparam(:dsc_psdscrunascredential) do + def mof_type; 'MSFT_Credential' end + def mof_is_embedded?; true end + desc "PsDscRunAsCredential" + validate do |value| + unless value.kind_of?(Hash) + fail("Invalid value '#{value}'. Should be a hash") + end + PuppetX::Dsc::TypeHelpers.validate_MSFT_Credential("Credential", value) + end + end + + # Name: ServerName + # Type: string + # IsMandatory: True + # Values: None + newparam(:dsc_servername) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "ServerName - Hostname of the SQL Server." + isrequired + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: InstanceName + # Type: string + # IsMandatory: True + # Values: None + newparam(:dsc_instancename) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "InstanceName - Name of the SQL instance." + isrequired + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: ServiceType + # Type: string + # IsMandatory: True + # Values: ["DatabaseEngine", "SQLServerAgent", "Search", "IntegrationServices", "AnalysisServices", "ReportingServices", "SQLServerBrowser", "NotificationServices"] + newparam(:dsc_servicetype) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "ServiceType - Type of service being managed. Valid values are DatabaseEngine, SQLServerAgent, Search, IntegrationServices, AnalysisServices, ReportingServices, SQLServerBrowser, NotificationServices." + isrequired + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + unless ['DatabaseEngine', 'databaseengine', 'SQLServerAgent', 'sqlserveragent', 'Search', 'search', 'IntegrationServices', 'integrationservices', 'AnalysisServices', 'analysisservices', 'ReportingServices', 'reportingservices', 'SQLServerBrowser', 'sqlserverbrowser', 'NotificationServices', 'notificationservices'].include?(value) + fail("Invalid value '#{value}'. Valid values are DatabaseEngine, SQLServerAgent, Search, IntegrationServices, AnalysisServices, ReportingServices, SQLServerBrowser, NotificationServices") + end + end + end + + # Name: ServiceAccount + # Type: MSFT_Credential + # IsMandatory: False + # Values: None + newparam(:dsc_serviceaccount) do + def mof_type; 'MSFT_Credential' end + def mof_is_embedded?; true end + desc "ServiceAccount - The service account that should be used when running the service." + validate do |value| + unless value.kind_of?(Hash) + fail("Invalid value '#{value}'. Should be a hash") + end + PuppetX::Dsc::TypeHelpers.validate_MSFT_Credential("ServiceAccount", value) + end + end + + # Name: RestartService + # Type: boolean + # IsMandatory: False + # Values: None + newparam(:dsc_restartservice) do + def mof_type; 'boolean' end + def mof_is_embedded?; false end + desc "RestartService - Determines whether the service is automatically restarted when a change to the configuration was needed." + validate do |value| + end + newvalues(true, false) + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_boolean(value.to_s) + end + end + + # Name: Force + # Type: boolean + # IsMandatory: False + # Values: None + newparam(:dsc_force) do + def mof_type; 'boolean' end + def mof_is_embedded?; false end + desc "Force - Forces the service account to be updated. Useful for password changes." + validate do |value| + end + newvalues(true, false) + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_boolean(value.to_s) + end + end + + # Name: ServiceAccountName + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_serviceaccountname) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "ServiceAccountName - Returns the service account username for the service." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + + def builddepends + pending_relations = super() + PuppetX::Dsc::TypeHelpers.ensure_reboot_relationship(self, pending_relations) + end +end + +Puppet::Type.type(:dsc_sqlserviceaccount).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do + confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) + defaultfor :operatingsystem => :windows + + mk_resource_methods +end diff --git a/lib/puppet/type/dsc_xsqlserversetup.rb b/lib/puppet/type/dsc_sqlsetup.rb similarity index 92% rename from lib/puppet/type/dsc_xsqlserversetup.rb rename to lib/puppet/type/dsc_sqlsetup.rb index 973432325..546202827 100644 --- a/lib/puppet/type/dsc_xsqlserversetup.rb +++ b/lib/puppet/type/dsc_sqlsetup.rb @@ -1,14 +1,14 @@ require 'pathname' -Puppet::Type.newtype(:dsc_xsqlserversetup) do +Puppet::Type.newtype(:dsc_sqlsetup) do require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' @doc = %q{ - The DSC xSQLServerSetup resource type. + The DSC SqlSetup resource type. Automatically generated from - 'xSQLServer/DSCResources/MSFT_xSQLServerSetup/MSFT_xSQLServerSetup.schema.mof' + 'SqlServerDsc/DSCResources/MSFT_SqlSetup/MSFT_SqlSetup.schema.mof' To learn more about PowerShell Desired State Configuration, please visit https://technet.microsoft.com/en-us/library/dn249912.aspx. @@ -24,10 +24,10 @@ fail('dsc_instancename is a required attribute') if self[:dsc_instancename].nil? end - def dscmeta_resource_friendly_name; 'xSQLServerSetup' end - def dscmeta_resource_name; 'MSFT_xSQLServerSetup' end - def dscmeta_module_name; 'xSQLServer' end - def dscmeta_module_version; '7.0.0.0' end + def dscmeta_resource_friendly_name; 'SqlSetup' end + def dscmeta_resource_name; 'MSFT_SqlSetup' end + def dscmeta_module_name; 'SqlServerDsc' end + def dscmeta_module_version; '11.0.0.0' end newparam(:name, :namevar => true ) do end @@ -87,22 +87,6 @@ def mof_is_embedded?; false end end end - # Name: SetupCredential - # Type: MSFT_Credential - # IsMandatory: False - # Values: None - newparam(:dsc_setupcredential) do - def mof_type; 'MSFT_Credential' end - def mof_is_embedded?; true end - desc "SetupCredential - Credential to be used to perform the installation." - validate do |value| - unless value.kind_of?(Hash) - fail("Invalid value '#{value}'. Should be a hash") - end - PuppetX::Dsc::TypeHelpers.validate_MSFT_Credential("SetupCredential", value) - end - end - # Name: SourceCredential # Type: MSFT_Credential # IsMandatory: False @@ -734,6 +718,24 @@ def mof_is_embedded?; false end end end + # Name: ASServerMode + # Type: string + # IsMandatory: False + # Values: ["MULTIDIMENSIONAL", "TABULAR", "POWERPIVOT"] + newparam(:dsc_asservermode) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "ASServerMode - The server mode for SQL Server Analysis Services instance. The default is to install in Multidimensional mode. Valid values in a cluster scenario are MULTIDIMENSIONAL or TABULAR. Parameter ASServerMode is case-sensitive. All values must be expressed in upper case. Valid values are MULTIDIMENSIONAL, TABULAR, POWERPIVOT." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + unless ['MULTIDIMENSIONAL', 'multidimensional', 'TABULAR', 'tabular', 'POWERPIVOT', 'powerpivot'].include?(value) + fail("Invalid value '#{value}'. Valid values are MULTIDIMENSIONAL, TABULAR, POWERPIVOT") + end + end + end + # Name: ISSvcAccount # Type: MSFT_Credential # IsMandatory: False @@ -823,7 +825,7 @@ def mof_is_embedded?; false end newparam(:dsc_failoverclusternetworkname) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "FailoverClusterNetworkName - Host name to be assigend to the clustered SQL Server instance." + desc "FailoverClusterNetworkName - Host name to be assigned to the clustered SQL Server instance." validate do |value| unless value.kind_of?(String) fail("Invalid value '#{value}'. Should be a string") @@ -831,6 +833,24 @@ def mof_is_embedded?; false end end end + # Name: SetupProcessTimeout + # Type: uint32 + # IsMandatory: False + # Values: None + newparam(:dsc_setupprocesstimeout) do + def mof_type; 'uint32' end + def mof_is_embedded?; false end + desc "SetupProcessTimeout - The timeout, in seconds, to wait for the setup process to finish. Default value is 7200 seconds (2 hours). If the setup process does not finish before this time, and error will be thrown." + validate do |value| + unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) + fail("Invalid value #{value}. Should be a unsigned Integer") + end + end + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_integer(value) + end + end + def builddepends pending_relations = super() @@ -838,7 +858,7 @@ def builddepends end end -Puppet::Type.type(:dsc_xsqlserversetup).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do +Puppet::Type.type(:dsc_sqlsetup).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) defaultfor :operatingsystem => :windows diff --git a/lib/puppet/type/dsc_xwaitforavailabilitygroup.rb b/lib/puppet/type/dsc_sqlwaitforag.rb similarity index 67% rename from lib/puppet/type/dsc_xwaitforavailabilitygroup.rb rename to lib/puppet/type/dsc_sqlwaitforag.rb index 9e35cf048..267494e77 100644 --- a/lib/puppet/type/dsc_xwaitforavailabilitygroup.rb +++ b/lib/puppet/type/dsc_sqlwaitforag.rb @@ -1,14 +1,14 @@ require 'pathname' -Puppet::Type.newtype(:dsc_xwaitforavailabilitygroup) do +Puppet::Type.newtype(:dsc_sqlwaitforag) do require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' @doc = %q{ - The DSC xWaitForAvailabilityGroup resource type. + The DSC SqlWaitForAG resource type. Automatically generated from - 'xSQLServer/DSCResources/MSFT_xWaitForAvailabilityGroup/MSFT_xWaitForAvailabilityGroup.schema.mof' + 'SqlServerDsc/DSCResources/MSFT_SqlWaitForAG/MSFT_SqlWaitForAG.schema.mof' To learn more about PowerShell Desired State Configuration, please visit https://technet.microsoft.com/en-us/library/dn249912.aspx. @@ -24,10 +24,10 @@ fail('dsc_name is a required attribute') if self[:dsc_name].nil? end - def dscmeta_resource_friendly_name; 'xWaitForAvailabilityGroup' end - def dscmeta_resource_name; 'MSFT_xWaitForAvailabilityGroup' end - def dscmeta_module_name; 'xSQLServer' end - def dscmeta_module_version; '7.0.0.0' end + def dscmeta_resource_friendly_name; 'SqlWaitForAG' end + def dscmeta_resource_name; 'MSFT_SqlWaitForAG' end + def dscmeta_module_name; 'SqlServerDsc' end + def dscmeta_module_version; '11.0.0.0' end newparam(:name, :namevar => true ) do end @@ -61,7 +61,7 @@ def mof_is_embedded?; true end newparam(:dsc_name) do def mof_type; 'string' end def mof_is_embedded?; false end - desc "Name - Availability Group Name" + desc "Name - Name of the cluster role/group to look for (normally the same as the Availability Group name)." isrequired validate do |value| unless value.kind_of?(String) @@ -77,7 +77,7 @@ def mof_is_embedded?; false end newparam(:dsc_retryintervalsec) do def mof_type; 'uint64' end def mof_is_embedded?; false end - desc "RetryIntervalSec - Interval to check for Availability Group" + desc "RetryIntervalSec - The interval, in seconds, to check for the presence of the cluster role/group. Default value is 20 seconds. When the cluster role/group has been found the resource will wait for this amount of time once more before returning." validate do |value| unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) fail("Invalid value #{value}. Should be a unsigned Integer") @@ -95,7 +95,7 @@ def mof_is_embedded?; false end newparam(:dsc_retrycount) do def mof_type; 'uint32' end def mof_is_embedded?; false end - desc "RetryCount - Maximum number of retries to check Availabilty group creation" + desc "RetryCount - Maximum number of retries until the resource will timeout and throw an error. Default values is 30 times." validate do |value| unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) fail("Invalid value #{value}. Should be a unsigned Integer") @@ -106,6 +106,22 @@ def mof_is_embedded?; false end end end + # Name: GroupExist + # Type: boolean + # IsMandatory: False + # Values: None + newparam(:dsc_groupexist) do + def mof_type; 'boolean' end + def mof_is_embedded?; false end + desc "GroupExist - Returns $true if the cluster role/group exist, otherwise it returns $false. Used by Get-TargetResource." + validate do |value| + end + newvalues(true, false) + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_boolean(value.to_s) + end + end + def builddepends pending_relations = super() @@ -113,7 +129,7 @@ def builddepends end end -Puppet::Type.type(:dsc_xwaitforavailabilitygroup).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do +Puppet::Type.type(:dsc_sqlwaitforag).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) defaultfor :operatingsystem => :windows diff --git a/lib/puppet/type/dsc_xsqlserverfirewall.rb b/lib/puppet/type/dsc_sqlwindowsfirewall.rb similarity index 93% rename from lib/puppet/type/dsc_xsqlserverfirewall.rb rename to lib/puppet/type/dsc_sqlwindowsfirewall.rb index f241489e3..dcddcb60c 100644 --- a/lib/puppet/type/dsc_xsqlserverfirewall.rb +++ b/lib/puppet/type/dsc_sqlwindowsfirewall.rb @@ -1,14 +1,14 @@ require 'pathname' -Puppet::Type.newtype(:dsc_xsqlserverfirewall) do +Puppet::Type.newtype(:dsc_sqlwindowsfirewall) do require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' @doc = %q{ - The DSC xSQLServerFirewall resource type. + The DSC SqlWindowsFirewall resource type. Automatically generated from - 'xSQLServer/DSCResources/MSFT_xSQLServerFirewall/MSFT_xSQLServerFirewall.schema.mof' + 'SqlServerDsc/DSCResources/MSFT_SqlWindowsFirewall/MSFT_SqlWindowsFirewall.schema.mof' To learn more about PowerShell Desired State Configuration, please visit https://technet.microsoft.com/en-us/library/dn249912.aspx. @@ -25,10 +25,10 @@ fail('dsc_instancename is a required attribute') if self[:dsc_instancename].nil? end - def dscmeta_resource_friendly_name; 'xSQLServerFirewall' end - def dscmeta_resource_name; 'MSFT_xSQLServerFirewall' end - def dscmeta_module_name; 'xSQLServer' end - def dscmeta_module_version; '7.0.0.0' end + def dscmeta_resource_friendly_name; 'SqlWindowsFirewall' end + def dscmeta_resource_name; 'MSFT_SqlWindowsFirewall' end + def dscmeta_module_name; 'SqlServerDsc' end + def dscmeta_module_version; '11.0.0.0' end newparam(:name, :namevar => true ) do end @@ -225,7 +225,7 @@ def builddepends end end -Puppet::Type.type(:dsc_xsqlserverfirewall).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do +Puppet::Type.type(:dsc_sqlwindowsfirewall).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) defaultfor :operatingsystem => :windows diff --git a/lib/puppet/type/dsc_xsqlaogroupjoin.rb b/lib/puppet/type/dsc_xsqlaogroupjoin.rb deleted file mode 100644 index 77d1281ee..000000000 --- a/lib/puppet/type/dsc_xsqlaogroupjoin.rb +++ /dev/null @@ -1,153 +0,0 @@ -require 'pathname' - -Puppet::Type.newtype(:dsc_xsqlaogroupjoin) do - require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' - require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' - - - @doc = %q{ - The DSC xSQLAOGroupJoin resource type. - Automatically generated from - 'xSQLServer/DSCResources/MSFT_xSQLAOGroupJoin/MSFT_xSQLAOGroupJoin.schema.mof' - - To learn more about PowerShell Desired State Configuration, please - visit https://technet.microsoft.com/en-us/library/dn249912.aspx. - - For more information about built-in DSC Resources, please visit - https://technet.microsoft.com/en-us/library/dn249921.aspx. - - For more information about xDsc Resources, please visit - https://github.com/PowerShell/DscResources. - } - - validate do - fail('dsc_ensure is a required attribute') if self[:dsc_ensure].nil? - fail('dsc_availabilitygroupname is a required attribute') if self[:dsc_availabilitygroupname].nil? - end - - def dscmeta_resource_friendly_name; 'xSQLAOGroupJoin' end - def dscmeta_resource_name; 'MSFT_xSQLAOGroupJoin' end - def dscmeta_module_name; 'xSQLServer' end - def dscmeta_module_version; '7.0.0.0' end - - newparam(:name, :namevar => true ) do - end - - ensurable do - newvalue(:exists?) { provider.exists? } - newvalue(:present) { provider.create } - newvalue(:absent) { provider.destroy } - defaultto { :present } - end - - # Name: PsDscRunAsCredential - # Type: MSFT_Credential - # IsMandatory: False - # Values: None - newparam(:dsc_psdscrunascredential) do - def mof_type; 'MSFT_Credential' end - def mof_is_embedded?; true end - desc "PsDscRunAsCredential" - validate do |value| - unless value.kind_of?(Hash) - fail("Invalid value '#{value}'. Should be a hash") - end - PuppetX::Dsc::TypeHelpers.validate_MSFT_Credential("Credential", value) - end - end - - # Name: Ensure - # Type: string - # IsMandatory: True - # Values: ["Present", "Absent"] - newparam(:dsc_ensure) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "Ensure - If the replica should be joined ('Present') to the Availability Group or not joined ('Absent') to the Availability Group. Valid values are Present, Absent." - isrequired - validate do |value| - resource[:ensure] = value.downcase - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - unless ['Present', 'present', 'Absent', 'absent'].include?(value) - fail("Invalid value '#{value}'. Valid values are Present, Absent") - end - end - end - - # Name: AvailabilityGroupName - # Type: string - # IsMandatory: True - # Values: None - newparam(:dsc_availabilitygroupname) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "AvailabilityGroupName - The name Availability Group to join." - isrequired - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: SQLServer - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_sqlserver) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "SQLServer - Name of the SQL server to be configured." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: SQLInstanceName - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_sqlinstancename) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "SQLInstanceName - Name of the SQL instance to be configured." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: SetupCredential - # Type: MSFT_Credential - # IsMandatory: False - # Values: None - newparam(:dsc_setupcredential) do - def mof_type; 'MSFT_Credential' end - def mof_is_embedded?; true end - desc "SetupCredential - Credential to be used to Grant Permissions in SQL." - validate do |value| - unless value.kind_of?(Hash) - fail("Invalid value '#{value}'. Should be a hash") - end - PuppetX::Dsc::TypeHelpers.validate_MSFT_Credential("SetupCredential", value) - end - end - - - def builddepends - pending_relations = super() - PuppetX::Dsc::TypeHelpers.ensure_reboot_relationship(self, pending_relations) - end -end - -Puppet::Type.type(:dsc_xsqlaogroupjoin).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do - confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) - defaultfor :operatingsystem => :windows - - mk_resource_methods -end diff --git a/lib/puppet/type/dsc_xsqlserveralwaysonservice.rb b/lib/puppet/type/dsc_xsqlserveralwaysonservice.rb deleted file mode 100644 index 683c9c8b6..000000000 --- a/lib/puppet/type/dsc_xsqlserveralwaysonservice.rb +++ /dev/null @@ -1,140 +0,0 @@ -require 'pathname' - -Puppet::Type.newtype(:dsc_xsqlserveralwaysonservice) do - require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' - require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' - - - @doc = %q{ - The DSC xSQLServerAlwaysOnService resource type. - Automatically generated from - 'xSQLServer/DSCResources/MSFT_xSQLServerAlwaysOnService/MSFT_xSQLServerAlwaysOnService.schema.mof' - - To learn more about PowerShell Desired State Configuration, please - visit https://technet.microsoft.com/en-us/library/dn249912.aspx. - - For more information about built-in DSC Resources, please visit - https://technet.microsoft.com/en-us/library/dn249921.aspx. - - For more information about xDsc Resources, please visit - https://github.com/PowerShell/DscResources. - } - - validate do - fail('dsc_sqlserver is a required attribute') if self[:dsc_sqlserver].nil? - fail('dsc_sqlinstancename is a required attribute') if self[:dsc_sqlinstancename].nil? - end - - def dscmeta_resource_friendly_name; 'xSQLServerAlwaysOnService' end - def dscmeta_resource_name; 'MSFT_xSQLServerAlwaysOnService' end - def dscmeta_module_name; 'xSQLServer' end - def dscmeta_module_version; '7.0.0.0' end - - newparam(:name, :namevar => true ) do - end - - ensurable do - newvalue(:exists?) { provider.exists? } - newvalue(:present) { provider.create } - newvalue(:absent) { provider.destroy } - defaultto { :present } - end - - # Name: PsDscRunAsCredential - # Type: MSFT_Credential - # IsMandatory: False - # Values: None - newparam(:dsc_psdscrunascredential) do - def mof_type; 'MSFT_Credential' end - def mof_is_embedded?; true end - desc "PsDscRunAsCredential" - validate do |value| - unless value.kind_of?(Hash) - fail("Invalid value '#{value}'. Should be a hash") - end - PuppetX::Dsc::TypeHelpers.validate_MSFT_Credential("Credential", value) - end - end - - # Name: Ensure - # Type: string - # IsMandatory: False - # Values: ["Present", "Absent"] - newparam(:dsc_ensure) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "Ensure - HADR is Present (enabled) or Absent (disabled) Valid values are Present, Absent." - validate do |value| - resource[:ensure] = value.downcase - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - unless ['Present', 'present', 'Absent', 'absent'].include?(value) - fail("Invalid value '#{value}'. Valid values are Present, Absent") - end - end - end - - # Name: SQLServer - # Type: string - # IsMandatory: True - # Values: None - newparam(:dsc_sqlserver) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "SQLServer - The hostname of the SQL Server to be configured" - isrequired - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: SQLInstanceName - # Type: string - # IsMandatory: True - # Values: None - newparam(:dsc_sqlinstancename) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "SQLInstanceName - Name of the SQL instance to be configured." - isrequired - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: RestartTimeout - # Type: sint32 - # IsMandatory: False - # Values: None - newparam(:dsc_restarttimeout) do - def mof_type; 'sint32' end - def mof_is_embedded?; false end - desc "RestartTimeout - The length of time, in seconds, to wait for the service to restart. Default is 120 seconds." - validate do |value| - unless value.kind_of?(Numeric) || value.to_i.to_s == value - fail("Invalid value #{value}. Should be a signed Integer") - end - end - munge do |value| - PuppetX::Dsc::TypeHelpers.munge_integer(value) - end - end - - - def builddepends - pending_relations = super() - PuppetX::Dsc::TypeHelpers.ensure_reboot_relationship(self, pending_relations) - end -end - -Puppet::Type.type(:dsc_xsqlserveralwaysonservice).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do - confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) - defaultfor :operatingsystem => :windows - - mk_resource_methods -end diff --git a/lib/puppet/type/dsc_xsqlserverfailoverclustersetup.rb b/lib/puppet/type/dsc_xsqlserverfailoverclustersetup.rb deleted file mode 100644 index 73af98fac..000000000 --- a/lib/puppet/type/dsc_xsqlserverfailoverclustersetup.rb +++ /dev/null @@ -1,795 +0,0 @@ -require 'pathname' - -Puppet::Type.newtype(:dsc_xsqlserverfailoverclustersetup) do - require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' - require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' - - - @doc = %q{ - The DSC xSQLServerFailoverClusterSetup resource type. - Automatically generated from - 'xSQLServer/DSCResources/MSFT_xSQLServerFailoverClusterSetup/MSFT_xSQLServerFailoverClusterSetup.schema.mof' - - To learn more about PowerShell Desired State Configuration, please - visit https://technet.microsoft.com/en-us/library/dn249912.aspx. - - For more information about built-in DSC Resources, please visit - https://technet.microsoft.com/en-us/library/dn249921.aspx. - - For more information about xDsc Resources, please visit - https://github.com/PowerShell/DscResources. - } - - validate do - fail('dsc_action is a required attribute') if self[:dsc_action].nil? - fail('dsc_instancename is a required attribute') if self[:dsc_instancename].nil? - end - - def dscmeta_resource_friendly_name; 'xSQLServerFailoverClusterSetup' end - def dscmeta_resource_name; 'MSFT_xSQLServerFailoverClusterSetup' end - def dscmeta_module_name; 'xSQLServer' end - def dscmeta_module_version; '7.0.0.0' end - - newparam(:name, :namevar => true ) do - end - - ensurable do - newvalue(:exists?) { provider.exists? } - newvalue(:present) { provider.create } - defaultto { :present } - end - - # Name: PsDscRunAsCredential - # Type: MSFT_Credential - # IsMandatory: False - # Values: None - newparam(:dsc_psdscrunascredential) do - def mof_type; 'MSFT_Credential' end - def mof_is_embedded?; true end - desc "PsDscRunAsCredential" - validate do |value| - unless value.kind_of?(Hash) - fail("Invalid value '#{value}'. Should be a hash") - end - PuppetX::Dsc::TypeHelpers.validate_MSFT_Credential("Credential", value) - end - end - - # Name: Action - # Type: string - # IsMandatory: True - # Values: ["Prepare", "Complete"] - newparam(:dsc_action) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "Action - Prepare or Complete. Valid values are Prepare, Complete." - isrequired - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - unless ['Prepare', 'prepare', 'Complete', 'complete'].include?(value) - fail("Invalid value '#{value}'. Valid values are Prepare, Complete") - end - end - end - - # Name: SourcePath - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_sourcepath) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "SourcePath - UNC path to the root of the source files for installation." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: SourceFolder - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_sourcefolder) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "SourceFolder - Folder within the source path containing the source files for installation." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: SetupCredential - # Type: MSFT_Credential - # IsMandatory: False - # Values: None - newparam(:dsc_setupcredential) do - def mof_type; 'MSFT_Credential' end - def mof_is_embedded?; true end - desc "SetupCredential - Credential to be used to perform the installation." - validate do |value| - unless value.kind_of?(Hash) - fail("Invalid value '#{value}'. Should be a hash") - end - PuppetX::Dsc::TypeHelpers.validate_MSFT_Credential("SetupCredential", value) - end - end - - # Name: SourceCredential - # Type: MSFT_Credential - # IsMandatory: False - # Values: None - newparam(:dsc_sourcecredential) do - def mof_type; 'MSFT_Credential' end - def mof_is_embedded?; true end - desc "SourceCredential - Credential to be used to access SourcePath." - validate do |value| - unless value.kind_of?(Hash) - fail("Invalid value '#{value}'. Should be a hash") - end - PuppetX::Dsc::TypeHelpers.validate_MSFT_Credential("SourceCredential", value) - end - end - - # Name: SuppressReboot - # Type: boolean - # IsMandatory: False - # Values: None - newparam(:dsc_suppressreboot) do - def mof_type; 'boolean' end - def mof_is_embedded?; false end - desc "SuppressReboot - Suppress reboot." - validate do |value| - end - newvalues(true, false) - munge do |value| - PuppetX::Dsc::TypeHelpers.munge_boolean(value.to_s) - end - end - - # Name: ForceReboot - # Type: boolean - # IsMandatory: False - # Values: None - newparam(:dsc_forcereboot) do - def mof_type; 'boolean' end - def mof_is_embedded?; false end - desc "ForceReboot - Force reboot." - validate do |value| - end - newvalues(true, false) - munge do |value| - PuppetX::Dsc::TypeHelpers.munge_boolean(value.to_s) - end - end - - # Name: Features - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_features) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "Features - SQL features to be installed." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: InstanceName - # Type: string - # IsMandatory: True - # Values: None - newparam(:dsc_instancename) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "InstanceName - SQL instance to be installed." - isrequired - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: InstanceID - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_instanceid) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "InstanceID - SQL instance ID, if different from InstanceName." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: PID - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_pid) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "PID - Product key for licensed installations." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: UpdateEnabled - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_updateenabled) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "UpdateEnabled - Enabled updates during installation." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: UpdateSource - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_updatesource) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "UpdateSource - Source of updates to be applied during installation." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: SQMReporting - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_sqmreporting) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "SQMReporting - Enable customer experience reporting." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: ErrorReporting - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_errorreporting) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "ErrorReporting - Enable error reporting." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: FailoverClusterGroup - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_failoverclustergroup) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "FailoverClusterGroup - Name of the resource group to be used for the SQL Server failover cluster." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: FailoverClusterNetworkName - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_failoverclusternetworkname) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "FailoverClusterNetworkName - Network name for the SQL Server failover cluster." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: FailoverClusterIPAddress - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_failoverclusteripaddress) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "FailoverClusterIPAddress - IPv4 address for the SQL Server failover cluster." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: InstallSharedDir - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_installshareddir) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "InstallSharedDir - Installation path for shared SQL files." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: InstallSharedWOWDir - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_installsharedwowdir) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "InstallSharedWOWDir - Installation path for x86 shared SQL files." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: InstanceDir - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_instancedir) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "InstanceDir - Installation path for SQL instance files." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: SQLSvcAccount - # Type: MSFT_Credential - # IsMandatory: False - # Values: None - newparam(:dsc_sqlsvcaccount) do - def mof_type; 'MSFT_Credential' end - def mof_is_embedded?; true end - desc "SQLSvcAccount - Service account for the SQL service." - validate do |value| - unless value.kind_of?(Hash) - fail("Invalid value '#{value}'. Should be a hash") - end - PuppetX::Dsc::TypeHelpers.validate_MSFT_Credential("SQLSvcAccount", value) - end - end - - # Name: SQLSvcAccountUsername - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_sqlsvcaccountusername) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "SQLSvcAccountUsername - Output username for the SQL service." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: AgtSvcAccount - # Type: MSFT_Credential - # IsMandatory: False - # Values: None - newparam(:dsc_agtsvcaccount) do - def mof_type; 'MSFT_Credential' end - def mof_is_embedded?; true end - desc "AgtSvcAccount - Service account for the SQL Agent service." - validate do |value| - unless value.kind_of?(Hash) - fail("Invalid value '#{value}'. Should be a hash") - end - PuppetX::Dsc::TypeHelpers.validate_MSFT_Credential("AgtSvcAccount", value) - end - end - - # Name: AgtSvcAccountUsername - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_agtsvcaccountusername) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "AgtSvcAccountUsername - Output username for the SQL Agent service." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: SQLCollation - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_sqlcollation) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "SQLCollation - Collation for SQL." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: SQLSysAdminAccounts - # Type: string[] - # IsMandatory: False - # Values: None - newparam(:dsc_sqlsysadminaccounts, :array_matching => :all) do - def mof_type; 'string[]' end - def mof_is_embedded?; false end - desc "SQLSysAdminAccounts - Array of accounts to be made SQL administrators." - validate do |value| - unless value.kind_of?(Array) || value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string or an array of strings") - end - end - munge do |value| - Array(value) - end - end - - # Name: SecurityMode - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_securitymode) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "SecurityMode - Security mode." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: SAPwd - # Type: MSFT_Credential - # IsMandatory: False - # Values: None - newparam(:dsc_sapwd) do - def mof_type; 'MSFT_Credential' end - def mof_is_embedded?; true end - desc "SAPwd - SA password, if SecurityMode=SQL" - validate do |value| - unless value.kind_of?(Hash) - fail("Invalid value '#{value}'. Should be a hash") - end - PuppetX::Dsc::TypeHelpers.validate_MSFT_Credential("SAPwd", value) - end - end - - # Name: InstallSQLDataDir - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_installsqldatadir) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "InstallSQLDataDir - Root path for SQL database files." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: SQLUserDBDir - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_sqluserdbdir) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "SQLUserDBDir - Path for SQL database files." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: SQLUserDBLogDir - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_sqluserdblogdir) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "SQLUserDBLogDir - Path for SQL log files." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: SQLTempDBDir - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_sqltempdbdir) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "SQLTempDBDir - Path for SQL TempDB files." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: SQLTempDBLogDir - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_sqltempdblogdir) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "SQLTempDBLogDir - Path for SQL TempDB log files." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: SQLBackupDir - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_sqlbackupdir) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "SQLBackupDir - Path for SQL backup files." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: ASSvcAccount - # Type: MSFT_Credential - # IsMandatory: False - # Values: None - newparam(:dsc_assvcaccount) do - def mof_type; 'MSFT_Credential' end - def mof_is_embedded?; true end - desc "ASSvcAccount - Service account for Analysus Services service." - validate do |value| - unless value.kind_of?(Hash) - fail("Invalid value '#{value}'. Should be a hash") - end - PuppetX::Dsc::TypeHelpers.validate_MSFT_Credential("ASSvcAccount", value) - end - end - - # Name: ASSvcAccountUsername - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_assvcaccountusername) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "ASSvcAccountUsername - Output username for the Analysis Services service." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: ASCollation - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_ascollation) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "ASCollation - Collation for Analysis Services." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: ASSysAdminAccounts - # Type: string[] - # IsMandatory: False - # Values: None - newparam(:dsc_assysadminaccounts, :array_matching => :all) do - def mof_type; 'string[]' end - def mof_is_embedded?; false end - desc "ASSysAdminAccounts - Array of accounts to be made Analysis Services admins." - validate do |value| - unless value.kind_of?(Array) || value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string or an array of strings") - end - end - munge do |value| - Array(value) - end - end - - # Name: ASDataDir - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_asdatadir) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "ASDataDir - Path for Analysis Services data files." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: ASLogDir - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_aslogdir) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "ASLogDir - Path for Analysis Services log files." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: ASBackupDir - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_asbackupdir) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "ASBackupDir - Path for Analysis Services backup files." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: ASTempDir - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_astempdir) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "ASTempDir - Path for Analysis Services temp files." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: ASConfigDir - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_asconfigdir) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "ASConfigDir - Path for Analysis Services config." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: ISSvcAccount - # Type: MSFT_Credential - # IsMandatory: False - # Values: None - newparam(:dsc_issvcaccount) do - def mof_type; 'MSFT_Credential' end - def mof_is_embedded?; true end - desc "ISSvcAccount - Service account for Integration Services service." - validate do |value| - unless value.kind_of?(Hash) - fail("Invalid value '#{value}'. Should be a hash") - end - PuppetX::Dsc::TypeHelpers.validate_MSFT_Credential("ISSvcAccount", value) - end - end - - # Name: ISSvcAccountUsername - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_issvcaccountusername) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "ISSvcAccountUsername - Output username for the Integration Services service." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: ISFileSystemFolder - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_isfilesystemfolder) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "ISFileSystemFolder - File system folder for Integration Services." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - - def builddepends - pending_relations = super() - PuppetX::Dsc::TypeHelpers.ensure_reboot_relationship(self, pending_relations) - end -end - -Puppet::Type.type(:dsc_xsqlserverfailoverclustersetup).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do - confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) - defaultfor :operatingsystem => :windows - - mk_resource_methods -end diff --git a/lib/puppet/type/dsc_xsqlserverrsconfig.rb b/lib/puppet/type/dsc_xsqlserverrsconfig.rb deleted file mode 100644 index cb641937a..000000000 --- a/lib/puppet/type/dsc_xsqlserverrsconfig.rb +++ /dev/null @@ -1,147 +0,0 @@ -require 'pathname' - -Puppet::Type.newtype(:dsc_xsqlserverrsconfig) do - require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' - require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' - - - @doc = %q{ - The DSC xSQLServerRSConfig resource type. - Automatically generated from - 'xSQLServer/DSCResources/MSFT_xSQLServerRSConfig/MSFT_xSQLServerRSConfig.schema.mof' - - To learn more about PowerShell Desired State Configuration, please - visit https://technet.microsoft.com/en-us/library/dn249912.aspx. - - For more information about built-in DSC Resources, please visit - https://technet.microsoft.com/en-us/library/dn249921.aspx. - - For more information about xDsc Resources, please visit - https://github.com/PowerShell/DscResources. - } - - validate do - fail('dsc_instancename is a required attribute') if self[:dsc_instancename].nil? - end - - def dscmeta_resource_friendly_name; 'xSQLServerRSConfig' end - def dscmeta_resource_name; 'MSFT_xSQLServerRSConfig' end - def dscmeta_module_name; 'xSQLServer' end - def dscmeta_module_version; '7.0.0.0' end - - newparam(:name, :namevar => true ) do - end - - ensurable do - newvalue(:exists?) { provider.exists? } - newvalue(:present) { provider.create } - defaultto { :present } - end - - # Name: PsDscRunAsCredential - # Type: MSFT_Credential - # IsMandatory: False - # Values: None - newparam(:dsc_psdscrunascredential) do - def mof_type; 'MSFT_Credential' end - def mof_is_embedded?; true end - desc "PsDscRunAsCredential" - validate do |value| - unless value.kind_of?(Hash) - fail("Invalid value '#{value}'. Should be a hash") - end - PuppetX::Dsc::TypeHelpers.validate_MSFT_Credential("Credential", value) - end - end - - # Name: InstanceName - # Type: string - # IsMandatory: True - # Values: None - newparam(:dsc_instancename) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "InstanceName - Name of the SQL Server Reporting Services instance to be configured." - isrequired - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: RSSQLServer - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_rssqlserver) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "RSSQLServer - Name of the SQL Server to host the Reporting Service database." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: RSSQLInstanceName - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_rssqlinstancename) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "RSSQLInstanceName - Name of the SQL Server instance to host the Reporting Service database." - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: SQLAdminCredential - # Type: MSFT_Credential - # IsMandatory: False - # Values: None - newparam(:dsc_sqladmincredential) do - def mof_type; 'MSFT_Credential' end - def mof_is_embedded?; true end - desc "SQLAdminCredential - Credential to be used to perform the configuration." - validate do |value| - unless value.kind_of?(Hash) - fail("Invalid value '#{value}'. Should be a hash") - end - PuppetX::Dsc::TypeHelpers.validate_MSFT_Credential("SQLAdminCredential", value) - end - end - - # Name: IsInitialized - # Type: boolean - # IsMandatory: False - # Values: None - newparam(:dsc_isinitialized) do - def mof_type; 'boolean' end - def mof_is_embedded?; false end - desc "IsInitialized - Is the Reporting Services instance initialized." - validate do |value| - end - newvalues(true, false) - munge do |value| - PuppetX::Dsc::TypeHelpers.munge_boolean(value.to_s) - end - end - - - def builddepends - pending_relations = super() - PuppetX::Dsc::TypeHelpers.ensure_reboot_relationship(self, pending_relations) - end -end - -Puppet::Type.type(:dsc_xsqlserverrsconfig).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do - confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) - defaultfor :operatingsystem => :windows - - mk_resource_methods -end diff --git a/lib/puppet/type/dsc_xsqlserverrssecureconnectionlevel.rb b/lib/puppet/type/dsc_xsqlserverrssecureconnectionlevel.rb deleted file mode 100644 index 008016de5..000000000 --- a/lib/puppet/type/dsc_xsqlserverrssecureconnectionlevel.rb +++ /dev/null @@ -1,121 +0,0 @@ -require 'pathname' - -Puppet::Type.newtype(:dsc_xsqlserverrssecureconnectionlevel) do - require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' - require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' - - - @doc = %q{ - The DSC xSQLServerRSSecureConnectionLevel resource type. - Automatically generated from - 'xSQLServer/DSCResources/MSFT_xSQLServerRSSecureConnectionLevel/MSFT_xSQLServerRSSecureConnectionLevel.schema.mof' - - To learn more about PowerShell Desired State Configuration, please - visit https://technet.microsoft.com/en-us/library/dn249912.aspx. - - For more information about built-in DSC Resources, please visit - https://technet.microsoft.com/en-us/library/dn249921.aspx. - - For more information about xDsc Resources, please visit - https://github.com/PowerShell/DscResources. - } - - validate do - fail('dsc_instancename is a required attribute') if self[:dsc_instancename].nil? - fail('dsc_secureconnectionlevel is a required attribute') if self[:dsc_secureconnectionlevel].nil? - end - - def dscmeta_resource_friendly_name; 'xSQLServerRSSecureConnectionLevel' end - def dscmeta_resource_name; 'MSFT_xSQLServerRSSecureConnectionLevel' end - def dscmeta_module_name; 'xSQLServer' end - def dscmeta_module_version; '7.0.0.0' end - - newparam(:name, :namevar => true ) do - end - - ensurable do - newvalue(:exists?) { provider.exists? } - newvalue(:present) { provider.create } - defaultto { :present } - end - - # Name: PsDscRunAsCredential - # Type: MSFT_Credential - # IsMandatory: False - # Values: None - newparam(:dsc_psdscrunascredential) do - def mof_type; 'MSFT_Credential' end - def mof_is_embedded?; true end - desc "PsDscRunAsCredential" - validate do |value| - unless value.kind_of?(Hash) - fail("Invalid value '#{value}'. Should be a hash") - end - PuppetX::Dsc::TypeHelpers.validate_MSFT_Credential("Credential", value) - end - end - - # Name: InstanceName - # Type: string - # IsMandatory: True - # Values: None - newparam(:dsc_instancename) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "InstanceName - SQL instance to set secure connection level for." - isrequired - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: SecureConnectionLevel - # Type: uint16 - # IsMandatory: True - # Values: None - newparam(:dsc_secureconnectionlevel) do - def mof_type; 'uint16' end - def mof_is_embedded?; false end - desc "SecureConnectionLevel - SQL Server Reporting Service secure connection level." - isrequired - validate do |value| - unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) - fail("Invalid value #{value}. Should be a unsigned Integer") - end - end - munge do |value| - PuppetX::Dsc::TypeHelpers.munge_integer(value) - end - end - - # Name: SQLAdminCredential - # Type: MSFT_Credential - # IsMandatory: False - # Values: None - newparam(:dsc_sqladmincredential) do - def mof_type; 'MSFT_Credential' end - def mof_is_embedded?; true end - desc "SQLAdminCredential - Credential with administrative permissions to the SQL instance." - validate do |value| - unless value.kind_of?(Hash) - fail("Invalid value '#{value}'. Should be a hash") - end - PuppetX::Dsc::TypeHelpers.validate_MSFT_Credential("SQLAdminCredential", value) - end - end - - - def builddepends - pending_relations = super() - PuppetX::Dsc::TypeHelpers.ensure_reboot_relationship(self, pending_relations) - end -end - -Puppet::Type.type(:dsc_xsqlserverrssecureconnectionlevel).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do - confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) - defaultfor :operatingsystem => :windows - - mk_resource_methods -end diff --git a/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/CommonResourceHelper.psm1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/CommonResourceHelper.psm1 new file mode 100644 index 000000000..bf18d83b8 --- /dev/null +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/CommonResourceHelper.psm1 @@ -0,0 +1,265 @@ +<# + .SYNOPSIS + Creates and throws an invalid argument exception. + + .PARAMETER Message + The message explaining why this error is being thrown. + + .PARAMETER ArgumentName + The name of the invalid argument that is causing this error to be thrown. +#> +function New-InvalidArgumentException +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $Message, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $ArgumentName + ) + + $argumentException = New-Object -TypeName 'ArgumentException' ` + -ArgumentList @($Message, $ArgumentName) + + $newObjectParameters = @{ + TypeName = 'System.Management.Automation.ErrorRecord' + ArgumentList = @($argumentException, $ArgumentName, 'InvalidArgument', $null) + } + + $errorRecord = New-Object @newObjectParameters + + throw $errorRecord +} + +<# + .SYNOPSIS + Creates and throws an invalid operation exception. + + .PARAMETER Message + The message explaining why this error is being thrown. + + .PARAMETER ErrorRecord + The error record containing the exception that is causing this terminating error. +#> +function New-InvalidOperationException +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $Message, + + [Parameter()] + [ValidateNotNull()] + [System.Management.Automation.ErrorRecord] + $ErrorRecord + ) + + if ($null -eq $ErrorRecord) + { + $invalidOperationException = New-Object -TypeName 'InvalidOperationException' ` + -ArgumentList @($Message) + } + else + { + $invalidOperationException = New-Object -TypeName 'InvalidOperationException' ` + -ArgumentList @($Message, $ErrorRecord.Exception) + } + + $newObjectParameters = @{ + TypeName = 'System.Management.Automation.ErrorRecord' + ArgumentList = @( + $invalidOperationException.ToString(), + 'MachineStateIncorrect', + 'InvalidOperation', + $null + ) + } + + $errorRecordToThrow = New-Object @newObjectParameters + + throw $errorRecordToThrow +} + +<# + .SYNOPSIS + Creates and throws an object not found exception. + + .PARAMETER Message + The message explaining why this error is being thrown. + + .PARAMETER ErrorRecord + The error record containing the exception that is causing this terminating error. +#> +function New-ObjectNotFoundException +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $Message, + + [Parameter()] + [ValidateNotNull()] + [System.Management.Automation.ErrorRecord] + $ErrorRecord + ) + + if ($null -eq $ErrorRecord) + { + $exception = New-Object -TypeName 'System.Exception' ` + -ArgumentList @($Message) + } + else + { + $exception = New-Object -TypeName 'System.Exception' ` + -ArgumentList @($Message, $ErrorRecord.Exception) + } + + $newObjectParameters = @{ + TypeName = 'System.Management.Automation.ErrorRecord' + ArgumentList = @( + $exception.ToString(), + 'MachineStateIncorrect', + 'ObjectNotFound', + $null + ) + } + + $errorRecordToThrow = New-Object @newObjectParameters + + throw $errorRecordToThrow +} + +<# + .SYNOPSIS + Creates and throws an invalid result exception. + + .PARAMETER Message + The message explaining why this error is being thrown. + + .PARAMETER ErrorRecord + The error record containing the exception that is causing this terminating error. +#> +function New-InvalidResultException +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $Message, + + [Parameter()] + [ValidateNotNull()] + [System.Management.Automation.ErrorRecord] + $ErrorRecord + ) + + if ($null -eq $ErrorRecord) + { + $exception = New-Object -TypeName 'System.Exception' ` + -ArgumentList @($Message) + } + else + { + $exception = New-Object -TypeName 'System.Exception' ` + -ArgumentList @($Message, $ErrorRecord.Exception) + } + + $newObjectParameters = @{ + TypeName = 'System.Management.Automation.ErrorRecord' + ArgumentList = @( + $exception.ToString(), + 'MachineStateIncorrect', + 'InvalidResult', + $null + ) + } + + $errorRecordToThrow = New-Object @newObjectParameters + + throw $errorRecordToThrow +} + +<# + .SYNOPSIS + Retrieves the localized string data based on the machine's culture. + Falls back to en-US strings if the machine's culture is not supported. + + .PARAMETER ResourceName + The name of the resource as it appears before '.strings.psd1' of the localized string file. + For example: + For WindowsOptionalFeature: MSFT_WindowsOptionalFeature + For Service: MSFT_ServiceResource + For Registry: MSFT_RegistryResource + For Helper: SqlServerDscHelper + + .PARAMETER ScriptRoot + Optional. The root path where to expect to find the culture folder. This is only needed + for localization in helper modules. This should not normally be used for resources. +#> +function Get-LocalizedData +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $ResourceName, + + [Parameter()] + [ValidateNotNullOrEmpty()] + [System.String] + $ScriptRoot + ) + + if ( -not $ScriptRoot ) + { + $resourceDirectory = Join-Path -Path $PSScriptRoot -ChildPath $ResourceName + $localizedStringFileLocation = Join-Path -Path $resourceDirectory -ChildPath $PSUICulture + } + else + { + $localizedStringFileLocation = Join-Path -Path $ScriptRoot -ChildPath $PSUICulture + } + + if (-not (Test-Path -Path $localizedStringFileLocation)) + { + # Fallback to en-US + if ( -not $ScriptRoot ) + { + $localizedStringFileLocation = Join-Path -Path $resourceDirectory -ChildPath 'en-US' + } + else + { + $localizedStringFileLocation = Join-Path -Path $ScriptRoot -ChildPath 'en-US' + } + } + + Import-LocalizedData ` + -BindingVariable 'localizedData' ` + -FileName "$ResourceName.strings.psd1" ` + -BaseDirectory $localizedStringFileLocation + + return $localizedData +} + +Export-ModuleMember -Function @( + 'New-InvalidArgumentException', + 'New-InvalidOperationException', + 'New-ObjectNotFoundException', + 'New-InvalidResultException', + 'Get-LocalizedData' ) diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAlwaysOnAvailabilityGroup/MSFT_xSQLServerAlwaysOnAvailabilityGroup.psm1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAG/MSFT_SqlAG.psm1 similarity index 55% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAlwaysOnAvailabilityGroup/MSFT_xSQLServerAlwaysOnAvailabilityGroup.psm1 rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAG/MSFT_SqlAG.psm1 index 41b3142cb..387c9e2b3 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAlwaysOnAvailabilityGroup/MSFT_xSQLServerAlwaysOnAvailabilityGroup.psm1 +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAG/MSFT_SqlAG.psm1 @@ -1,41 +1,44 @@ Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) ` - -ChildPath 'xSQLServerHelper.psm1') ` - -Force + -ChildPath 'SqlServerDscHelper.psm1') ` + -Force <# .SYNOPSIS - Gets the specified Availabilty Group. - + Gets the specified Availability Group. + .PARAMETER Name The name of the availability group. - .PARAMETER SQLServer + .PARAMETER ServerName Hostname of the SQL Server to be configured. - - .PARAMETER SQLInstanceName - Name of the SQL instance to be configued. + + .PARAMETER InstanceName + Name of the SQL instance to be configured. #> function Get-TargetResource { [CmdletBinding()] - [OutputType([Hashtable])] + [OutputType([System.Collections.Hashtable])] param ( - [parameter(Mandatory = $true)] - [String] + [Parameter(Mandatory = $true)] + [System.String] $Name, - + [Parameter(Mandatory = $true)] - [String] - $SQLServer, - + [System.String] + $ServerName, + [Parameter(Mandatory = $true)] - [String] - $SQLInstanceName + [System.String] + $InstanceName ) - + # Connect to the instance - $serverObject = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName + $serverObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName + + # Define current version for check compatibility + $sqlMajorVersion = $serverObject.Version.Major # Get the endpoint properties $endpoint = $serverObject.Endpoints | Where-Object { $_.EndpointType -eq 'DatabaseMirroring' } @@ -43,46 +46,45 @@ function Get-TargetResource { $endpointPort = $endpoint.Protocol.Tcp.ListenerPort } - + # Get the Availability Group $availabilityGroup = $serverObject.AvailabilityGroups[$Name] + # Is this node actively hosting the SQL instance? + $isActiveNode = Test-ActiveNode -ServerObject $serverObject + + # Create the return object. Default ensure to Absent. + $alwaysOnAvailabilityGroupResource = @{ + Name = $Name + ServerName = $ServerName + InstanceName = $InstanceName + Ensure = 'Absent' + IsActiveNode = $isActiveNode + } + if ( $availabilityGroup ) { # Get all of the properties that can be set using this resource - $alwaysOnAvailabilityGroupResource = @{ - Name = $Name - SQLServer = $SQLServer - SQLInstanceName = $SQLInstanceName - Ensure = 'Present' - AutomatedBackupPreference = $availabilityGroup.AutomatedBackupPreference - AvailabilityMode = $availabilityGroup.AvailabilityReplicas[$serverObject.Name].AvailabilityMode - BackupPriority = $availabilityGroup.AvailabilityReplicas[$serverObject.Name].BackupPriority - ConnectionModeInPrimaryRole = $availabilityGroup.AvailabilityReplicas[$serverObject.Name].ConnectionModeInPrimaryRole - ConnectionModeInSecondaryRole = $availabilityGroup.AvailabilityReplicas[$serverObject.Name].ConnectionModeInSecondaryRole - FailureConditionLevel = $availabilityGroup.FailureConditionLevel - FailoverMode = $availabilityGroup.AvailabilityReplicas[$serverObject.Name].FailoverMode - HealthCheckTimeout = $availabilityGroup.HealthCheckTimeout - EndpointURL = $availabilityGroup.AvailabilityReplicas[$serverObject.Name].EndpointUrl - EndpointPort = $endpointPort - SQLServerNetName = $serverObject.NetName - Version = $serverObject.Version.Major - } + $alwaysOnAvailabilityGroupResource.Ensure = 'Present' + $alwaysOnAvailabilityGroupResource.AutomatedBackupPreference = $availabilityGroup.AutomatedBackupPreference + $alwaysOnAvailabilityGroupResource.AvailabilityMode = $availabilityGroup.AvailabilityReplicas[$serverObject.DomainInstanceName].AvailabilityMode + $alwaysOnAvailabilityGroupResource.BackupPriority = $availabilityGroup.AvailabilityReplicas[$serverObject.DomainInstanceName].BackupPriority + $alwaysOnAvailabilityGroupResource.ConnectionModeInPrimaryRole = $availabilityGroup.AvailabilityReplicas[$serverObject.DomainInstanceName].ConnectionModeInPrimaryRole + $alwaysOnAvailabilityGroupResource.ConnectionModeInSecondaryRole = $availabilityGroup.AvailabilityReplicas[$serverObject.DomainInstanceName].ConnectionModeInSecondaryRole + $alwaysOnAvailabilityGroupResource.FailureConditionLevel = $availabilityGroup.FailureConditionLevel + $alwaysOnAvailabilityGroupResource.FailoverMode = $availabilityGroup.AvailabilityReplicas[$serverObject.DomainInstanceName].FailoverMode + $alwaysOnAvailabilityGroupResource.HealthCheckTimeout = $availabilityGroup.HealthCheckTimeout + $alwaysOnAvailabilityGroupResource.EndpointURL = $availabilityGroup.AvailabilityReplicas[$serverObject.DomainInstanceName].EndpointUrl + $alwaysOnAvailabilityGroupResource.EndpointPort = $endpointPort + $alwaysOnAvailabilityGroupResource.EndpointHostName = $serverObject.NetName + $alwaysOnAvailabilityGroupResource.Version = $sqlMajorVersion # Add properties that are only present in SQL 2016 or newer - if ( $serverObject.Version.Major -ge 13 ) + if ( $sqlMajorVersion -ge 13 ) { $alwaysOnAvailabilityGroupResource.Add('BasicAvailabilityGroup', $availabilityGroup.BasicAvailabilityGroup) - } - } - else - { - # Return the minimum amount of properties showing that the Availabilty Group is absent - $alwaysOnAvailabilityGroupResource = @{ - Name = $Name - SQLServer = $SQLServer - SQLInstanceName = $SQLInstanceName - Ensure = 'Absent' + $alwaysOnAvailabilityGroupResource.Add('DatabaseHealthTrigger', $availabilityGroup.DatabaseHealthTrigger) + $alwaysOnAvailabilityGroupResource.Add('DtcSupportEnabled', $availabilityGroup.DtcSupportEnabled) } } @@ -92,15 +94,15 @@ function Get-TargetResource <# .SYNOPSIS Creates or removes the availability group to in accordance with the desired state. - + .PARAMETER Name The name of the availability group. - .PARAMETER SQLServer + .PARAMETER ServerName Hostname of the SQL Server to be configured. - - .PARAMETER SQLInstanceName - Name of the SQL instance to be configued. + + .PARAMETER InstanceName + Name of the SQL instance to be configured. .PARAMETER Ensure Specifies if the availability group should be present or absent. Default is Present. @@ -117,6 +119,12 @@ function Get-TargetResource .PARAMETER BasicAvailabilityGroup Specifies the type of availability group is Basic. This is only available is SQL Server 2016 and later and is ignored when applied to previous versions. + .PARAMETER DatabaseHealthTrigger + Specifies if the option Database Level Health Detection is enabled. This is only available is SQL Server 2016 and later and is ignored when applied to previous versions. + + .PARAMETER DtcSupportEnabled + Specifies if the option Database DTC Support is enabled. This is only available is SQL Server 2016 and later and is ignored when applied to previous versions. This can't be altered once the Availability Group is created and is ignored if it is the case. + .PARAMETER ConnectionModeInPrimaryRole Specifies how the availability replica handles connections when in the primary role. @@ -131,6 +139,10 @@ function Get-TargetResource .PARAMETER HealthCheckTimeout Specifies the length of time, in milliseconds, after which AlwaysOn availability groups declare an unresponsive server to be unhealthy. Default is 30,000. + + .PARAMETER ProcessOnlyOnActiveNode + Specifies that the resource will only determine if a change is needed if the target node is the active host of the SQL Server Instance. + Not used in Set-TargetResource. #> function Set-TargetResource { @@ -138,53 +150,61 @@ function Set-TargetResource Param ( [Parameter(Mandatory = $true)] - [String] + [System.String] $Name, - + [Parameter(Mandatory = $true)] - [String] - $SQLServer, + [System.String] + $ServerName, [Parameter(Mandatory = $true)] - [String] - $SQLInstanceName, + [System.String] + $InstanceName, [Parameter()] - [ValidateSet('Present','Absent')] - [String] + [ValidateSet('Present', 'Absent')] + [System.String] $Ensure = 'Present', [Parameter()] - [ValidateSet('Primary','SecondaryOnly','Secondary','None')] - [String] + [ValidateSet('Primary', 'SecondaryOnly', 'Secondary', 'None')] + [System.String] $AutomatedBackupPreference = 'None', [Parameter()] - [ValidateSet('AsynchronousCommit','SynchronousCommit')] - [String] + [ValidateSet('AsynchronousCommit', 'SynchronousCommit')] + [System.String] $AvailabilityMode = 'AsynchronousCommit', - + [Parameter()] - [ValidateRange(0,100)] - [UInt32] + [ValidateRange(0, 100)] + [System.UInt32] $BackupPriority = 50, [Parameter()] - [bool] + [System.Boolean] $BasicAvailabilityGroup, [Parameter()] - [ValidateSet('AllowAllConnections','AllowReadWriteConnections')] - [String] + [System.Boolean] + $DatabaseHealthTrigger, + + [Parameter()] + [System.Boolean] + $DtcSupportEnabled, + + [Parameter()] + [ValidateSet('AllowAllConnections', 'AllowReadWriteConnections')] + [System.String] $ConnectionModeInPrimaryRole, [Parameter()] - [ValidateSet('AllowNoConnections','AllowReadIntentConnectionsOnly','AllowAllConnections')] - [String] + [ValidateSet('AllowNoConnections', 'AllowReadIntentConnectionsOnly', 'AllowAllConnections')] + [System.String] $ConnectionModeInSecondaryRole, [Parameter()] - [String] + [System.String] $EndpointHostName, [Parameter()] @@ -195,33 +215,38 @@ function Set-TargetResource 'OnModerateServerErrors', 'OnAnyQualifiedFailureCondition' )] - [String] + [System.String] $FailureConditionLevel, [Parameter()] - [ValidateSet('Automatic','Manual')] - [String] + [ValidateSet('Automatic', 'Manual')] + [System.String] $FailoverMode = 'Manual', [Parameter()] - [UInt32] - $HealthCheckTimeout = 30000 + [System.UInt32] + $HealthCheckTimeout = 30000, + + [Parameter()] + [System.Boolean] + $ProcessOnlyOnActiveNode ) - + Import-SQLPSModule - + # Connect to the instance - $serverObject = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName + $serverObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName # Determine if HADR is enabled on the instance. If not, throw an error if ( -not $serverObject.IsHadrEnabled ) { - throw New-TerminatingError -ErrorType HadrNotEnabled -FormatArgs $Ensure,$SQLInstanceName -ErrorCategory NotImplemented + throw New-TerminatingError -ErrorType HadrNotEnabled -FormatArgs $Ensure, $InstanceName -ErrorCategory NotImplemented } - $version = $serverObject.Version.Major + # Define current version for check compatibility + $sqlMajorVersion = $serverObject.Version.Major - # Get the Availabilty Group if it exists + # Get the Availability Group if it exists $availabilityGroup = $serverObject.AvailabilityGroups[$Name] switch ($Ensure) @@ -232,7 +257,7 @@ function Set-TargetResource if ( $availabilityGroup ) { # If the primary replica is currently on this instance - if ( $availabilityGroup.PrimaryReplicaServerName -eq $serverObject.Name ) + if ( $availabilityGroup.PrimaryReplicaServerName -eq $serverObject.DomainInstanceName ) { try { @@ -240,118 +265,59 @@ function Set-TargetResource } catch { - throw New-TerminatingError -ErrorType RemoveAvailabilityGroupFailed -FormatArgs $availabilityGroup.Name,$SQLInstanceName -ErrorCategory ResourceUnavailable + throw New-TerminatingError -ErrorType RemoveAvailabilityGroupFailed -FormatArgs $availabilityGroup.Name, $InstanceName -ErrorCategory ResourceUnavailable -InnerException $_.Exception } } else { - throw New-TerminatingError -ErrorType InstanceNotPrimaryReplica -FormatArgs $SQLInstanceName,$availabilityGroup.Name -ErrorCategory ResourceUnavailable + throw New-TerminatingError -ErrorType InstanceNotPrimaryReplica -FormatArgs $InstanceName, $availabilityGroup.Name -ErrorCategory ResourceUnavailable } } } Present { - $clusterServiceName = 'NT SERVICE\ClusSvc' - $ntAuthoritySystemName = 'NT AUTHORITY\SYSTEM' - $availabilityGroupManagementPerms = @('Connect SQL','Alter Any Availability Group','View Server State') - $clusterPermissionsPresent = $false - - foreach ( $loginName in @( $clusterServiceName, $ntAuthoritySystemName ) ) - { - if ( $serverObject.Logins[$loginName] ) - { - $testLoginEffectivePermissionsParams = @{ - SQLServer = $SQLServer - SQLInstanceName = $SQLInstanceName - LoginName = $loginName - Permissions = $availabilityGroupManagementPerms - } - - $clusterPermissionsPresent = Test-LoginEffectivePermissions @testLoginEffectivePermissionsParams - - if ( $clusterPermissionsPresent ) - { - # Exit the loop when the script verifies the required cluster permissions are present - break - } - else - { - switch ( $loginName ) - { - $clusterServiceName - { - New-VerboseMessage -Message "The recommended account '$loginName' is missing one or more of the following permissions: $( $availabilityGroupManagementPerms -join ', ' ). Trying with '$ntAuthoritySystemName'." - } - - $ntAuthoritySystemName - { - New-VerboseMessage -Message "'$loginName' is missing one or more of the following permissions: $( $availabilityGroupManagementPerms -join ', ' )" - } - } - } - } - else - { - switch ( $loginName ) - { - $clusterServiceName - { - New-VerboseMessage -Message "The recommended login '$loginName' is not present. Trying with '$ntAuthoritySystemName'." - } - - $ntAuthoritySystemName - { - New-VerboseMessage -Message "The login '$loginName' is not present." - } - } - } - } - - # If neither 'NT SERVICE\ClusSvc' or 'NT AUTHORITY\SYSTEM' have the required permissions, throw an error - if ( -not $clusterPermissionsPresent ) - { - throw New-TerminatingError -ErrorType ClusterPermissionsMissing -FormatArgs $SQLServer,$SQLInstanceName -ErrorCategory SecurityError - } + # Ensure the appropriate cluster permissions are present + Test-ClusterPermissions -ServerObject $serverObject + # Make sure a database mirroring endpoint exists. $endpoint = $serverObject.Endpoints | Where-Object { $_.EndpointType -eq 'DatabaseMirroring' } if ( -not $endpoint ) { - throw New-TerminatingError -ErrorType DatabaseMirroringEndpointNotFound -FormatArgs $SQLServer,$SQLInstanceName -ErrorCategory ObjectNotFound + throw New-TerminatingError -ErrorType DatabaseMirroringEndpointNotFound -FormatArgs $ServerName, $InstanceName -ErrorCategory ObjectNotFound } if ( -not $EndpointHostName ) { $EndpointHostName = $serverObject.NetName } - + # If the availability group does not exist, create it if ( -not $availabilityGroup ) { - # Set up the parameters to create the AG Replica $newReplicaParams = @{ - Name = $serverObject.Name - Version = $version - AsTemplate = $true + Name = $serverObject.DomainInstanceName + Version = $sqlMajorVersion + AsTemplate = $true AvailabilityMode = $AvailabilityMode - EndpointUrl = "TCP://$($EndpointHostName):$($endpoint.Protocol.Tcp.ListenerPort)" - FailoverMode = $FailoverMode + EndpointUrl = "TCP://$($EndpointHostName):$($endpoint.Protocol.Tcp.ListenerPort)" + FailoverMode = $FailoverMode } if ( $BackupPriority ) { - $newReplicaParams.Add('BackupPriority',$BackupPriority) + $newReplicaParams.Add('BackupPriority', $BackupPriority) } if ( $ConnectionModeInPrimaryRole ) { - $newReplicaParams.Add('ConnectionModeInPrimaryRole',$ConnectionModeInPrimaryRole) + $newReplicaParams.Add('ConnectionModeInPrimaryRole', $ConnectionModeInPrimaryRole) } - + if ( $ConnectionModeInSecondaryRole ) { - $newReplicaParams.Add('ConnectionModeInSecondaryRole',$ConnectionModeInSecondaryRole) + $newReplicaParams.Add('ConnectionModeInSecondaryRole', $ConnectionModeInSecondaryRole) } # Create the new replica object @@ -361,132 +327,140 @@ function Set-TargetResource } catch { - throw New-TerminatingError -ErrorType CreateAvailabilityGroupReplicaFailed -FormatArgs $Ensure,$SQLInstanceName -ErrorCategory OperationStopped + throw New-TerminatingError -ErrorType CreateAvailabilityGroupReplicaFailed -FormatArgs $newReplicaParams.Name, $InstanceName -ErrorCategory OperationStopped -InnerException $_.Exception } # Set up the parameters for the new availability group $newAvailabilityGroupParams = @{ - InputObject = $serverObject - Name = $Name + InputObject = $serverObject + Name = $Name AvailabilityReplica = $primaryReplica } if ( $AutomatedBackupPreference ) { - $newAvailabilityGroupParams.Add('AutomatedBackupPreference',$AutomatedBackupPreference) + $newAvailabilityGroupParams.Add('AutomatedBackupPreference', $AutomatedBackupPreference) } - - if ( $BasicAvailabilityGroup -and ( $version -ge 13 ) ) + + if ( $sqlMajorVersion -ge 13 ) { - $newAvailabilityGroupParams.Add('BasicAvailabilityGroup',$BasicAvailabilityGroup) + $newAvailabilityGroupParams.Add('BasicAvailabilityGroup', $BasicAvailabilityGroup) + $newAvailabilityGroupParams.Add('DatabaseHealthTrigger', $DatabaseHealthTrigger) + $newAvailabilityGroupParams.Add('DtcSupportEnabled', $DtcSupportEnabled) } - + if ( $FailureConditionLevel ) { - $newAvailabilityGroupParams.Add('FailureConditionLevel',$FailureConditionLevel) + $newAvailabilityGroupParams.Add('FailureConditionLevel', $FailureConditionLevel) } - + if ( $HealthCheckTimeout ) { - $newAvailabilityGroupParams.Add('HealthCheckTimeout',$HealthCheckTimeout) + $newAvailabilityGroupParams.Add('HealthCheckTimeout', $HealthCheckTimeout) } - - # Create the Availabilty Group - try + + # Create the Availability Group + try { New-SqlAvailabilityGroup @newAvailabilityGroupParams -ErrorAction Stop } catch { - throw New-TerminatingError -ErrorType CreateAvailabilityGroupFailed -FormatArgs $Name,$_.Exception -ErrorCategory OperationStopped + throw New-TerminatingError -ErrorType CreateAvailabilityGroupFailed -FormatArgs $Name -ErrorCategory OperationStopped -InnerException $_.Exception } } # Otherwise let's check each of the parameters passed and update the Availability Group accordingly else - { + { + # Get the parameters that were submitted to the function + [System.Array] $submittedParameters = $PSBoundParameters.Keys + # Make sure we're communicating with the primary replica - if ( $availabilityGroup.LocalReplicaRole -ne 'Primary' ) - { - $primaryServerObject = Connect-SQL -SQLServer $availabilityGroup.PrimaryReplicaServerName - $availabilityGroup = $primaryServerObject.AvailabilityGroups[$Name] - } - - if ( $AutomatedBackupPreference -ne $availabilityGroup.AutomatedBackupPreference ) + $primaryServerObject = Get-PrimaryReplicaServerObject -ServerObject $serverObject -AvailabilityGroup $availabilityGroup + $availabilityGroup = $primaryServerObject.AvailabilityGroups[$Name] + + if ( ( $submittedParameters -contains 'AutomatedBackupPreference' ) -and ( $AutomatedBackupPreference -ne $availabilityGroup.AutomatedBackupPreference ) ) { $availabilityGroup.AutomatedBackupPreference = $AutomatedBackupPreference Update-AvailabilityGroup -AvailabilityGroup $availabilityGroup } - if ( $AvailabilityMode -ne $availabilityGroup.AvailabilityReplicas[$serverObject.Name].AvailabilityMode ) + if ( ( $submittedParameters -contains 'AvailabilityMode' ) -and ( $AvailabilityMode -ne $availabilityGroup.AvailabilityReplicas[$serverObject.DomainInstanceName].AvailabilityMode ) ) { - $availabilityGroup.AvailabilityReplicas[$serverObject.Name].AvailabilityMode = $AvailabilityMode - Update-AvailabilityGroupReplica -AvailabilityGroupReplica $availabilityGroup.AvailabilityReplicas[$serverObject.Name] + $availabilityGroup.AvailabilityReplicas[$serverObject.DomainInstanceName].AvailabilityMode = $AvailabilityMode + Update-AvailabilityGroupReplica -AvailabilityGroupReplica $availabilityGroup.AvailabilityReplicas[$serverObject.DomainInstanceName] } - if ( $BackupPriority -ne $availabilityGroup.AvailabilityReplicas[$serverObject.Name].BackupPriority ) + if ( ( $submittedParameters -contains 'BackupPriority' ) -and ( $BackupPriority -ne $availabilityGroup.AvailabilityReplicas[$serverObject.DomainInstanceName].BackupPriority ) ) { - $availabilityGroup.AvailabilityReplicas[$serverObject.Name].BackupPriority = $BackupPriority - Update-AvailabilityGroupReplica -AvailabilityGroupReplica $availabilityGroup.AvailabilityReplicas[$serverObject.Name] + $availabilityGroup.AvailabilityReplicas[$serverObject.DomainInstanceName].BackupPriority = $BackupPriority + Update-AvailabilityGroupReplica -AvailabilityGroupReplica $availabilityGroup.AvailabilityReplicas[$serverObject.DomainInstanceName] } - if ( $BasicAvailabilityGroup -and ( $version -ge 13 ) -and ( $BasicAvailabilityGroup -ne $availabilityGroup.BasicAvailabilityGroup ) ) + if ( ( $submittedParameters -contains 'BasicAvailabilityGroup' ) -and ( $sqlMajorVersion -ge 13 ) -and ( $BasicAvailabilityGroup -ne $availabilityGroup.BasicAvailabilityGroup ) ) { $availabilityGroup.BasicAvailabilityGroup = $BasicAvailabilityGroup Update-AvailabilityGroup -AvailabilityGroup $availabilityGroup } + if ( ( $submittedParameters -contains 'DatabaseHealthTrigger' ) -and ( $sqlMajorVersion -ge 13 ) -and ( $DatabaseHealthTrigger -ne $availabilityGroup.DatabaseHealthTrigger ) ) + { + $availabilityGroup.DatabaseHealthTrigger = $DatabaseHealthTrigger + Update-AvailabilityGroup -AvailabilityGroup $availabilityGroup + } + # Make sure ConnectionModeInPrimaryRole has a value in order to avoid false positive matches when the parameter is not defined - if ( ( -not [string]::IsNullOrEmpty($ConnectionModeInPrimaryRole) ) -and ( $ConnectionModeInPrimaryRole -ne $availabilityGroup.AvailabilityReplicas[$serverObject.Name].ConnectionModeInPrimaryRole ) ) + if ( ( $submittedParameters -contains 'ConnectionModeInPrimaryRole' ) -and ( -not [System.String]::IsNullOrEmpty($ConnectionModeInPrimaryRole) ) -and ( $ConnectionModeInPrimaryRole -ne $availabilityGroup.AvailabilityReplicas[$serverObject.DomainInstanceName].ConnectionModeInPrimaryRole ) ) { - $availabilityGroup.AvailabilityReplicas[$serverObject.Name].ConnectionModeInPrimaryRole = $ConnectionModeInPrimaryRole - Update-AvailabilityGroupReplica -AvailabilityGroupReplica $availabilityGroup.AvailabilityReplicas[$serverObject.Name] + $availabilityGroup.AvailabilityReplicas[$serverObject.DomainInstanceName].ConnectionModeInPrimaryRole = $ConnectionModeInPrimaryRole + Update-AvailabilityGroupReplica -AvailabilityGroupReplica $availabilityGroup.AvailabilityReplicas[$serverObject.DomainInstanceName] } # Make sure ConnectionModeInSecondaryRole has a value in order to avoid false positive matches when the parameter is not defined - if ( ( -not [string]::IsNullOrEmpty($ConnectionModeInSecondaryRole) ) -and ( $ConnectionModeInSecondaryRole -ne $availabilityGroup.AvailabilityReplicas[$serverObject.Name].ConnectionModeInSecondaryRole ) ) + if ( ( $submittedParameters -contains 'ConnectionModeInSecondaryRole' ) -and ( -not [System.String]::IsNullOrEmpty($ConnectionModeInSecondaryRole) ) -and ( $ConnectionModeInSecondaryRole -ne $availabilityGroup.AvailabilityReplicas[$serverObject.DomainInstanceName].ConnectionModeInSecondaryRole ) ) { - $availabilityGroup.AvailabilityReplicas[$serverObject.Name].ConnectionModeInSecondaryRole = $ConnectionModeInSecondaryRole - Update-AvailabilityGroupReplica -AvailabilityGroupReplica $availabilityGroup.AvailabilityReplicas[$serverObject.Name] + $availabilityGroup.AvailabilityReplicas[$serverObject.DomainInstanceName].ConnectionModeInSecondaryRole = $ConnectionModeInSecondaryRole + Update-AvailabilityGroupReplica -AvailabilityGroupReplica $availabilityGroup.AvailabilityReplicas[$serverObject.DomainInstanceName] } - + # Break out the EndpointUrl properties - $currentEndpointProtocol, $currentEndpointHostName, $currentEndpointPort = $availabilityGroup.AvailabilityReplicas[$serverObject.Name].EndpointUrl.Replace('//','').Split(':') + $currentEndpointProtocol, $currentEndpointHostName, $currentEndpointPort = $availabilityGroup.AvailabilityReplicas[$serverObject.DomainInstanceName].EndpointUrl.Replace('//', '').Split(':') if ( $endpoint.Protocol.Tcp.ListenerPort -ne $currentEndpointPort ) { - $newEndpointUrl = $availabilityGroup.AvailabilityReplicas[$serverObject.Name].EndpointUrl.Replace($currentEndpointPort,$endpoint.Protocol.Tcp.ListenerPort) - $availabilityGroup.AvailabilityReplicas[$serverObject.Name].EndpointUrl = $newEndpointUrl - Update-AvailabilityGroupReplica -AvailabilityGroupReplica $availabilityGroup.AvailabilityReplicas[$serverObject.Name] + $newEndpointUrl = $availabilityGroup.AvailabilityReplicas[$serverObject.DomainInstanceName].EndpointUrl.Replace($currentEndpointPort, $endpoint.Protocol.Tcp.ListenerPort) + $availabilityGroup.AvailabilityReplicas[$serverObject.DomainInstanceName].EndpointUrl = $newEndpointUrl + Update-AvailabilityGroupReplica -AvailabilityGroupReplica $availabilityGroup.AvailabilityReplicas[$serverObject.DomainInstanceName] } - if ( $EndpointHostName -ne $currentEndpointHostName ) + if ( ( $submittedParameters -contains 'EndpointHostName' ) -and ( $EndpointHostName -ne $currentEndpointHostName ) ) { - $newEndpointUrl = $availabilityGroup.AvailabilityReplicas[$serverObject.Name].EndpointUrl.Replace($currentEndpointHostName,$EndpointHostName) - $availabilityGroup.AvailabilityReplicas[$serverObject.Name].EndpointUrl = $newEndpointUrl - Update-AvailabilityGroupReplica -AvailabilityGroupReplica $availabilityGroup.AvailabilityReplicas[$serverObject.Name] + $newEndpointUrl = $availabilityGroup.AvailabilityReplicas[$serverObject.DomainInstanceName].EndpointUrl.Replace($currentEndpointHostName, $EndpointHostName) + $availabilityGroup.AvailabilityReplicas[$serverObject.DomainInstanceName].EndpointUrl = $newEndpointUrl + Update-AvailabilityGroupReplica -AvailabilityGroupReplica $availabilityGroup.AvailabilityReplicas[$serverObject.DomainInstanceName] } if ( $currentEndpointProtocol -ne 'TCP' ) { - $newEndpointUrl = $availabilityGroup.AvailabilityReplicas[$serverObject.Name].EndpointUrl.Replace($currentEndpointProtocol,'TCP') - $availabilityGroup.AvailabilityReplicas[$serverObject.Name].EndpointUrl = $newEndpointUrl - Update-AvailabilityGroupReplica -AvailabilityGroupReplica $availabilityGroup.AvailabilityReplicas[$serverObject.Name] + $newEndpointUrl = $availabilityGroup.AvailabilityReplicas[$serverObject.DomainInstanceName].EndpointUrl.Replace($currentEndpointProtocol, 'TCP') + $availabilityGroup.AvailabilityReplicas[$serverObject.DomainInstanceName].EndpointUrl = $newEndpointUrl + Update-AvailabilityGroupReplica -AvailabilityGroupReplica $availabilityGroup.AvailabilityReplicas[$serverObject.DomainInstanceName] } # Make sure FailureConditionLevel has a value in order to avoid false positive matches when the parameter is not defined - if ( ( -not [string]::IsNullOrEmpty($FailureConditionLevel) ) -and ( $FailureConditionLevel -ne $availabilityGroup.FailureConditionLevel ) ) + if ( ( $submittedParameters -contains 'FailureConditionLevel' ) -and ( -not [System.String]::IsNullOrEmpty($FailureConditionLevel) ) -and ( $FailureConditionLevel -ne $availabilityGroup.FailureConditionLevel ) ) { $availabilityGroup.FailureConditionLevel = $FailureConditionLevel Update-AvailabilityGroup -AvailabilityGroup $availabilityGroup } - if ( $FailoverMode -ne $availabilityGroup.AvailabilityReplicas[$serverObject.Name].FailoverMode ) + if ( ( $submittedParameters -contains 'FailoverMode' ) -and ( $FailoverMode -ne $availabilityGroup.AvailabilityReplicas[$serverObject.DomainInstanceName].FailoverMode ) ) { - $availabilityGroup.AvailabilityReplicas[$serverObject.Name].AvailabilityMode = $FailoverMode - Update-AvailabilityGroupReplica -AvailabilityGroupReplica $availabilityGroup.AvailabilityReplicas[$serverObject.Name] + $availabilityGroup.AvailabilityReplicas[$serverObject.DomainInstanceName].FailoverMode = $FailoverMode + Update-AvailabilityGroupReplica -AvailabilityGroupReplica $availabilityGroup.AvailabilityReplicas[$serverObject.DomainInstanceName] } - - if ( $HealthCheckTimeout -ne $availabilityGroup.HealthCheckTimeout ) + + if ( ( $submittedParameters -contains 'HealthCheckTimeout' ) -and ( $HealthCheckTimeout -ne $availabilityGroup.HealthCheckTimeout ) ) { $availabilityGroup.HealthCheckTimeout = $HealthCheckTimeout Update-AvailabilityGroup -AvailabilityGroup $availabilityGroup @@ -499,15 +473,15 @@ function Set-TargetResource <# .SYNOPSIS Determines if the availability group is in the desired state. - + .PARAMETER Name The name of the availability group. - .PARAMETER SQLServer + .PARAMETER ServerName Hostname of the SQL Server to be configured. - - .PARAMETER SQLInstanceName - Name of the SQL instance to be configued. + + .PARAMETER InstanceName + Name of the SQL instance to be configured. .PARAMETER Ensure Specifies if the availability group should be present or absent. Default is Present. @@ -524,6 +498,12 @@ function Set-TargetResource .PARAMETER BasicAvailabilityGroup Specifies the type of availability group is Basic. This is only available is SQL Server 2016 and later and is ignored when applied to previous versions. + .PARAMETER DatabaseHealthTrigger + Specifies if the option Database Level Health Detection is enabled. This is only available is SQL Server 2016 and later and is ignored when applied to previous versions. + + .PARAMETER DtcSupportEnabled + Specifies if the option Database DTC Support is enabled. This is only available is SQL Server 2016 and later and is ignored when applied to previous versions. + .PARAMETER ConnectionModeInPrimaryRole Specifies how the availability replica handles connections when in the primary role. @@ -538,6 +518,9 @@ function Set-TargetResource .PARAMETER HealthCheckTimeout Specifies the length of time, in milliseconds, after which AlwaysOn availability groups declare an unresponsive server to be unhealthy. Default is 30,000. + + .PARAMETER ProcessOnlyOnActiveNode + Specifies that the resource will only determine if a change is needed if the target node is the active host of the SQL Server Instance. #> function Test-TargetResource { @@ -546,81 +529,106 @@ function Test-TargetResource Param ( [Parameter(Mandatory = $true)] - [String] + [System.String] $Name, - + [Parameter(Mandatory = $true)] - [String] - $SQLServer, + [System.String] + $ServerName, [Parameter(Mandatory = $true)] - [String] - $SQLInstanceName, + [System.String] + $InstanceName, [Parameter()] - [ValidateSet('Present','Absent')] - [String] + [ValidateSet('Present', 'Absent')] + [System.String] $Ensure = 'Present', [Parameter()] - [ValidateSet('Primary','SecondaryOnly','Secondary','None')] - [String] + [ValidateSet('Primary', 'SecondaryOnly', 'Secondary', 'None')] + [System.String] $AutomatedBackupPreference = 'None', [Parameter()] - [ValidateSet('AsynchronousCommit','SynchronousCommit')] - [String] + [ValidateSet('AsynchronousCommit', 'SynchronousCommit')] + [System.String] $AvailabilityMode = 'AsynchronousCommit', - + [Parameter()] - [ValidateRange(0,100)] - [UInt32] + [ValidateRange(0, 100)] + [System.UInt32] $BackupPriority = 50, [Parameter()] - [bool] + [System.Boolean] $BasicAvailabilityGroup, [Parameter()] - [ValidateSet('AllowAllConnections','AllowReadWriteConnections')] - [String] + [System.Boolean] + $DatabaseHealthTrigger, + + [Parameter()] + [System.Boolean] + $DtcSupportEnabled, + + [Parameter()] + [ValidateSet('AllowAllConnections', 'AllowReadWriteConnections')] + [System.String] $ConnectionModeInPrimaryRole, [Parameter()] - [ValidateSet('AllowNoConnections','AllowReadIntentConnectionsOnly','AllowAllConnections')] - [String] + [ValidateSet('AllowNoConnections', 'AllowReadIntentConnectionsOnly', 'AllowAllConnections')] + [System.String] $ConnectionModeInSecondaryRole, [Parameter()] - [String] + [System.String] $EndpointHostName, [Parameter()] - [ValidateSet('OnServerDown','OnServerUnresponsive','OnCriticalServerErrors','OnModerateServerErrors','OnAnyQualifiedFailureCondition')] - [String] + [ValidateSet('OnServerDown', 'OnServerUnresponsive', 'OnCriticalServerErrors', 'OnModerateServerErrors', 'OnAnyQualifiedFailureCondition')] + [System.String] $FailureConditionLevel, [Parameter()] - [ValidateSet('Automatic','Manual')] - [String] + [ValidateSet('Automatic', 'Manual')] + [System.String] $FailoverMode = 'Manual', [Parameter()] - [UInt32] - $HealthCheckTimeout = 30000 + [System.UInt32] + $HealthCheckTimeout = 30000, + + [Parameter()] + [System.Boolean] + $ProcessOnlyOnActiveNode ) $getTargetResourceParameters = @{ - SQLInstanceName = $SQLInstanceName - SQLServer = $SQLServer - Name = $Name + InstanceName = $InstanceName + ServerName = $ServerName + Name = $Name } - + # Assume this will pass. We will determine otherwise later $result = $true $getTargetResourceResult = Get-TargetResource @getTargetResourceParameters + <# + If this is supposed to process only the active node, and this is not the + active node, don't bother evaluating the test. + #> + if ( $ProcessOnlyOnActiveNode -and -not $getTargetResourceResult.IsActiveNode ) + { + New-VerboseMessage -Message ( 'The node "{0}" is not actively hosting the instance "{1}". Exiting the test.' -f $env:COMPUTERNAME, $InstanceName ) + return $result + } + + # Define current version for check compatibility + $sqlMajorVersion = $getTargetResourceResult.Version + switch ($Ensure) { 'Absent' @@ -631,7 +639,7 @@ function Test-TargetResource } else { - $result = $false + $result = $false } } @@ -639,59 +647,62 @@ function Test-TargetResource { $parametersToCheck = @( 'Name', - 'SQLServer', - 'SQLInstanceName', + 'ServerName', + 'InstanceName', 'Ensure', 'AutomatedBackupPreference', 'AvailabilityMode', 'BackupPriority', - 'BasicAvailabilityGroup', 'ConnectionModeInPrimaryRole', 'ConnectionModeInSecondaryRole', 'FailureConditionLevel', 'FailoverMode', 'HealthCheckTimeout' ) - + + <# + Add properties compatible with SQL Server 2016 or later versions + DtcSupportEnabled is enabled at the creation of the Availability Group only, hence it will not be checked in this block + #> + if ( $sqlMajorVersion -ge 13 ) + { + $parametersToCheck += 'BasicAvailabilityGroup' + $parametersToCheck += 'DatabaseHealthTrigger' + } + if ( $getTargetResourceResult.Ensure -eq 'Present' ) { - # PsBoundParameters won't work here because it doesn't account for default values - foreach ( $parameter in $MyInvocation.MyCommand.Parameters.GetEnumerator() ) + # Use $PSBoundParameters rather than $MyInvocation.MyCommand.Parameters.GetEnumerator() + # This allows us to only validate the supplied parameters + # If the parameter is not defined by the configuration, we don't care what + # it gets set to. + foreach ( $parameter in $PSBoundParameters.GetEnumerator() ) { $parameterName = $parameter.Key $parameterValue = Get-Variable -Name $parameterName -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Value - + # Make sure we don't try to validate a common parameter if ( $parametersToCheck -notcontains $parameterName ) { continue } - + if ( $getTargetResourceResult.($parameterName) -ne $parameterValue ) { - if ( $parameterName -eq 'BasicAvailabilityGroup' ) - { - # Move on to the next property if the instance is not at least SQL Server 2016 - if ( $getTargetResourceResult.Version -lt 13 ) - { - continue - } - } - New-VerboseMessage -Message "'$($parameterName)' should be '$($parameterValue)' but is '$($getTargetResourceResult.($parameterName))'" - + $result = $False } } # Get the Endpoint URL properties - $currentEndpointProtocol, $currentEndpointHostName, $currentEndpointPort = $getTargetResourceResult.EndpointUrl.Replace('//','').Split(':') + $currentEndpointProtocol, $currentEndpointHostName, $currentEndpointPort = $getTargetResourceResult.EndpointUrl.Replace('//', '').Split(':') if ( -not $EndpointHostName ) { - $EndpointHostName = $getTargetResourceResult.SQLServerNetName + $EndpointHostName = $getTargetResourceResult.EndpointHostName } - + # Verify the hostname in the endpoint URL is correct if ( $EndpointHostName -ne $currentEndpointHostName ) { @@ -726,9 +737,9 @@ function Test-TargetResource <# .SYNOPSIS Executes the alter method on an Availability Group object. - + .PARAMETER AvailabilityGroup - The Availabilty Group object that must be altered. + The Availability Group object that must be altered. #> function Update-AvailabilityGroup { @@ -747,7 +758,7 @@ function Update-AvailabilityGroup } catch { - throw New-TerminatingError -ErrorType AlterAvailabilityGroupFailed -FormatArgs $AvailabilityGroup.Name -ErrorCategory OperationStopped + throw New-TerminatingError -ErrorType AlterAvailabilityGroupFailed -FormatArgs $AvailabilityGroup.Name -ErrorCategory OperationStopped -InnerException $_.Exception } finally { diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAlwaysOnAvailabilityGroup/MSFT_xSQLServerAlwaysOnAvailabilityGroup.schema.mof b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAG/MSFT_SqlAG.schema.mof similarity index 67% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAlwaysOnAvailabilityGroup/MSFT_xSQLServerAlwaysOnAvailabilityGroup.schema.mof rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAG/MSFT_SqlAG.schema.mof index 07947f4d4..60031896c 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAlwaysOnAvailabilityGroup/MSFT_xSQLServerAlwaysOnAvailabilityGroup.schema.mof +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAG/MSFT_SqlAG.schema.mof @@ -1,18 +1,25 @@ -[ClassVersion("1.0.0.0"), FriendlyName("xSQLServerAlwaysOnAvailabilityGroup")] -class MSFT_xSQLServerAlwaysOnAvailabilityGroup : OMI_BaseResource +[ClassVersion("1.0.0.0"), FriendlyName("SqlAG")] +class MSFT_SqlAG : OMI_BaseResource { [Key, Description("The name of the availability group.")] String Name; - [Required, Description("Hostname of the SQL Server to be configured.")] String SQLServer; - [Key, Description("Name of the SQL instance to be configued.")] String SQLInstanceName; + [Required, Description("Hostname of the SQL Server to be configured.")] String ServerName; + [Key, Description("Name of the SQL instance to be configured.")] String InstanceName; [Write, Description("Specifies if the availability group should be present or absent. Default is Present."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; [Write, Description("Specifies the automated backup preference for the availability group. Default is None"), ValueMap{"Primary","SecondaryOnly","Secondary","None"}, Values{"Primary","SecondaryOnly","Secondary","None"}] String AutomatedBackupPreference; [Write, Description("Specifies the replica availability mode. Default is 'AsynchronousCommit'."), ValueMap{"AsynchronousCommit","SynchronousCommit"}, Values{"AsynchronousCommit","SynchronousCommit"}] String AvailabilityMode; [Write, Description("Specifies the desired priority of the replicas in performing backups. The acceptable values for this parameter are: integers from 0 through 100. Of the set of replicas which are online and available, the replica that has the highest priority performs the backup. Default is 50.")] UInt32 BackupPriority; [Write, Description("Specifies the type of availability group is Basic. This is only available is SQL Server 2016 and later and is ignored when applied to previous versions.")] Boolean BasicAvailabilityGroup; + [Write, Description("Specifies if the option Database Level Health Detection is enabled. This is only available is SQL Server 2016 and later and is ignored when applied to previous versions.")] Boolean DatabaseHealthTrigger; + [Write, Description("Specifies if the option Database DTC Support is enabled. This is only available is SQL Server 2016 and later and is ignored when applied to previous versions. This can't be altered once the Availability Group is created and is ignored if it is the case.")] Boolean DtcSupportEnabled; [Write, Description("Specifies how the availability replica handles connections when in the primary role."), ValueMap{"AllowAllConnections","AllowReadWriteConnections"}, Values{"AllowAllConnections","AllowReadWriteConnections"}] String ConnectionModeInPrimaryRole; [Write, Description("Specifies how the availability replica handles connections when in the secondary role."), ValueMap{"AllowNoConnections","AllowReadIntentConnectionsOnly","AllowAllConnections"}, Values{"AllowNoConnections","AllowReadIntentConnectionsOnly","AllowAllConnections"}] String ConnectionModeInSecondaryRole; [Write, Description("Specifies the hostname or IP address of the availability group replica endpoint. Default is the instance network name.")] String EndpointHostName; [Write, Description("Specifies the automatic failover behavior of the availability group."), ValueMap{"OnServerDown","OnServerUnresponsive","OnCriticalServerErrors","OnModerateServerErrors","OnAnyQualifiedFailureCondition"}, Values{"OnServerDown","OnServerUnresponsive","OnCriticalServerErrors","OnModerateServerErrors","OnAnyQualifiedFailureCondition"}] String FailureConditionLevel; [Write, Description("Specifies the failover mode. Default is 'Manual'."), ValueMap{"Automatic","Manual"}, Values{"Automatic","Manual"}] String FailoverMode; [Write, Description("Specifies the length of time, in milliseconds, after which AlwaysOn availability groups declare an unresponsive server to be unhealthy. Default is 30000.")] UInt32 HealthCheckTimeout; + [Write, Description("Specifies that the resource will only determine if a change is needed if the target node is the active host of the SQL Server Instance.")] Boolean ProcessOnlyOnActiveNode; + [Read, Description("Gets the Endpoint URL of the availability group replica endpoint.")] String EndpointUrl; + [Read, Description("Gets the port the database mirroring endpoint is listening on.")] UInt32 EndpointPort; + [Read, Description("Gets the major version of the SQL Server instance.")] UInt32 Version; + [Read, Description("Determines if the current node is actively hosting the SQL Server instance.")] Boolean IsActiveNode; }; diff --git a/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAGDatabase/MSFT_SqlAGDatabase.psm1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAGDatabase/MSFT_SqlAGDatabase.psm1 new file mode 100644 index 000000000..b934b1331 --- /dev/null +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAGDatabase/MSFT_SqlAGDatabase.psm1 @@ -0,0 +1,986 @@ +Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) ` + -ChildPath 'SqlServerDscHelper.psm1') ` + -Force + +Import-Module -Name (Join-Path -Path (Split-Path -Path $PSScriptRoot -Parent) ` + -ChildPath 'CommonResourceHelper.psm1') + +$script:localizedData = Get-LocalizedData -ResourceName 'MSFT_SqlAGDatabase' + +<# + .SYNOPSIS + Gets the database membership of the specified availability group. + + .PARAMETER DatabaseName + The name of the database(s) to add to the availability group. This accepts wildcards. + + .PARAMETER ServerName + Hostname of the SQL Server where the primary replica of the availability group lives. If the + availability group is not currently on this server, the resource will attempt to connect to the + server where the primary replica lives. + + .PARAMETER InstanceName + Name of the SQL instance where the primary replica of the availability group lives. If the + availability group is not currently on this instance, the resource will attempt to connect to + the instance where the primary replica lives. + + .PARAMETER AvailabilityGroupName + The name of the availability group in which to manage the database membership(s). + + .PARAMETER BackupPath + The path used to seed the availability group replicas. This should be a path that is accessible + by all of the replicas. +#> +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter(Mandatory = $true)] + [System.String[]] + $DatabaseName, + + [Parameter(Mandatory = $true)] + [System.String] + $ServerName, + + [Parameter(Mandatory = $true)] + [System.String] + $InstanceName, + + [Parameter(Mandatory = $true)] + [System.String] + $AvailabilityGroupName, + + [Parameter(Mandatory = $true)] + [System.String] + $BackupPath + ) + + # Create an object that reflects the current configuration + $currentConfiguration = @{ + DatabaseName = @() + ServerName = $ServerName + InstanceName = $InstanceName + AvailabilityGroupName = '' + BackupPath = '' + Ensure = '' + Force = $false + MatchDatabaseOwner = $false + IsActiveNode = $false + } + + # Connect to the instance + $serverObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName + + # Is this node actively hosting the SQL instance? + $currentConfiguration.IsActiveNode = Test-ActiveNode -ServerObject $serverObject + + # Get the Availability group object + $availabilityGroup = $serverObject.AvailabilityGroups[$AvailabilityGroupName] + + if ( $availabilityGroup ) + { + $currentConfiguration.AvailabilityGroupName = $AvailabilityGroupName + + # Get the databases in the availability group + $currentConfiguration.DatabaseName = $availabilityGroup.AvailabilityDatabases | Select-Object -ExpandProperty Name + } + else + { + Write-Verbose -Message ($script:localizedData.AvailabilityGroupDoesNotExist -f $AvailabilityGroupName) + } + + return $currentConfiguration +} + +<# + .SYNOPSIS + Adds or removes databases to the specified availability group. + + .PARAMETER DatabaseName + The name of the database(s) to add to the availability group. This accepts wildcards. + + .PARAMETER ServerName + Hostname of the SQL Server where the primary replica of the availability group lives. If the + availability group is not currently on this server, the resource will attempt to connect to the + server where the primary replica lives. + + .PARAMETER InstanceName + Name of the SQL instance where the primary replica of the availability group lives. If the + availability group is not currently on this instance, the resource will attempt to connect to + the instance where the primary replica lives. + + .PARAMETER AvailabilityGroupName + The name of the availability group in which to manage the database membership(s). + + .PARAMETER BackupPath + The path used to seed the availability group replicas. This should be a path that is accessible + by all of the replicas. + + .PARAMETER Ensure + Specifies the membership of the database(s) in the availability group. The options are: + + - Present: The defined database(s) are added to the availability group. All other + databases that may be a member of the availability group are ignored. + - Absent: The defined database(s) are removed from the availability group. All other + databases that may be a member of the availability group are ignored. + + The default is 'Present'. + + .PARAMETER Force + When used with "Ensure = 'Present'" it ensures the specified database(s) are the only databases + that are a member of the specified Availability Group. + + This parameter is ignored when 'Ensure' is 'Absent'. + + .PARAMETER MatchDatabaseOwner + If set to $true, this ensures the database owner of the database on the primary replica is the + owner of the database on all secondary replicas. This requires the database owner is available + as a login on all replicas and that the PSDscRunAsCredential has impersonate permissions. + + If set to $false, the owner of the database will be the PSDscRunAsCredential. + + The default is '$true'. + + .PARAMETER ProcessOnlyOnActiveNode + Specifies that the resource will only determine if a change is needed if the target node is the active host of the SQL Server Instance. + Not used in Set-TargetResource. +#> +function Set-TargetResource +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [System.String[]] + $DatabaseName, + + [Parameter(Mandatory = $true)] + [System.String] + $ServerName, + + [Parameter(Mandatory = $true)] + [System.String] + $InstanceName, + + [Parameter(Mandatory = $true)] + [System.String] + $AvailabilityGroupName, + + [Parameter(Mandatory = $true)] + [System.String] + $BackupPath, + + [Parameter()] + [ValidateSet('Present', 'Absent')] + [System.String] + $Ensure = 'Present', + + [Parameter()] + [System.Boolean] + $Force, + + [Parameter()] + [System.Boolean] + $MatchDatabaseOwner, + + [Parameter()] + [System.Boolean] + $ProcessOnlyOnActiveNode + ) + + Import-SQLPSModule + + # Connect to the defined instance + $serverObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName + + # Get the Availability Group + $availabilityGroup = $serverObject.AvailabilityGroups[$AvailabilityGroupName] + + # Make sure we're communicating with the primary replica in order to make changes to the replica + $primaryServerObject = Get-PrimaryReplicaServerObject -ServerObject $serverObject -AvailabilityGroup $availabilityGroup + + $getDatabasesToAddToAvailabilityGroupParameters = @{ + DatabaseName = $DatabaseName + Ensure = $Ensure + ServerObject = $primaryServerObject + AvailabilityGroup = $availabilityGroup + } + $databasesToAddToAvailabilityGroup = Get-DatabasesToAddToAvailabilityGroup @getDatabasesToAddToAvailabilityGroupParameters + + $getDatabasesToRemoveFromAvailabilityGroupParameters = @{ + DatabaseName = $DatabaseName + Ensure = $Ensure + Force = $Force + ServerObject = $primaryServerObject + AvailabilityGroup = $availabilityGroup + } + $databasesToRemoveFromAvailabilityGroup = Get-DatabasesToRemoveFromAvailabilityGroup @getDatabasesToRemoveFromAvailabilityGroupParameters + + # Create a hash table to store the databases that failed to be added to the Availability Group + $databasesToAddFailures = @{} + + # Create a hash table to store the databases that failed to be added to the Availability Group + $databasesToRemoveFailures = @{} + + if ( $databasesToAddToAvailabilityGroup.Count -gt 0 ) + { + Write-Verbose -Message ($script:localizedData.AddingDatabasesToAvailabilityGroup -f $AvailabilityGroupName, ( $databasesToAddToAvailabilityGroup -join ', ' )) + + # Get only the secondary replicas. Some tests do not need to be performed on the primary replica + $secondaryReplicas = $availabilityGroup.AvailabilityReplicas | Where-Object -FilterScript { $_.Role -ne 'Primary' } + + # Ensure the appropriate permissions are in place on all the replicas + if ( $MatchDatabaseOwner ) + { + $impersonatePermissionsStatus = @{} + + foreach ( $availabilityGroupReplica in $secondaryReplicas ) + { + $currentAvailabilityGroupReplicaServerObject = Connect-SQL -SQLServer $availabilityGroupReplica.Name + $impersonatePermissionsStatus.Add( + $availabilityGroupReplica.Name, + ( Test-ImpersonatePermissions -ServerObject $currentAvailabilityGroupReplicaServerObject ) + ) + } + + if ( $impersonatePermissionsStatus.Values -contains $false ) + { + $impersonatePermissionsMissingParameters = @( + [System.Security.Principal.WindowsIdentity]::GetCurrent().Name, + ( ( $impersonatePermissionsStatus.GetEnumerator() | Where-Object -FilterScript { -not $_.Value } | Select-Object -ExpandProperty Key ) -join ', ' ) + ) + throw ($script:localizedData.ImpersonatePermissionsMissing -f $impersonatePermissionsMissingParameters ) + } + } + + foreach ( $databaseToAddToAvailabilityGroup in $databasesToAddToAvailabilityGroup ) + { + $databaseObject = $primaryServerObject.Databases[$databaseToAddToAvailabilityGroup] + + <# + Verify the prerequisites prior to joining the database to the availability group + https://docs.microsoft.com/en-us/sql/database-engine/availability-groups/windows/prereqs-restrictions-recommendations-always-on-availability#a-nameprerequisitesfordbsa-availability-database-prerequisites-and-restrictions + #> + + # Create a hash table to store prerequisite check failures + $prerequisiteCheckFailures = @() + + $prerequisiteChecks = @{ + RecoveryModel = 'Full' + ReadOnly = $false + UserAccess = 'Multiple' + AutoClose = $false + AvailabilityGroupName = '' + IsMirroringEnabled = $false + } + + foreach ( $prerequisiteCheck in $prerequisiteChecks.GetEnumerator() ) + { + if ( $databaseObject.($prerequisiteCheck.Key) -ne $prerequisiteCheck.Value ) + { + $prerequisiteCheckFailures += "$($prerequisiteCheck.Key) is not $($prerequisiteCheck.Value)." + } + } + + # Cannot be a system database + if ( $databaseObject.ID -le 4 ) + { + $prerequisiteCheckFailures += 'The database cannot be a system database.' + } + + # If FILESTREAM is enabled, ensure FILESTREAM is enabled on all replica instances + if ( + ( -not [System.String]::IsNullOrEmpty($databaseObject.DefaultFileStreamFileGroup) ) ` + -or ( -not [System.String]::IsNullOrEmpty($databaseObject.FilestreamDirectoryName) ) ` + -or ( $databaseObject.FilestreamNonTransactedAccess -ne 'Off' ) + ) + { + $availabilityReplicaFilestreamLevel = @{} + foreach ( $availabilityGroupReplica in $secondaryReplicas ) + { + $connectSqlParameters = Split-FullSQLInstanceName -FullSQLInstanceName $availabilityGroupReplica.Name + $currentAvailabilityGroupReplicaServerObject = Connect-SQL @connectSqlParameters + $availabilityReplicaFilestreamLevel.Add($availabilityGroupReplica.Name, $currentAvailabilityGroupReplicaServerObject.FilestreamLevel) + } + + if ( $availabilityReplicaFilestreamLevel.Values -contains 'Disabled' ) + { + $availabilityReplicaFilestreamLevelDisabled = $availabilityReplicaFilestreamLevel.GetEnumerator() | Where-Object { $_.Value -eq 'Disabled' } | Select-Object -ExpandProperty Key + $prerequisiteCheckFailures += ( 'Filestream is disabled on the following instances: {0}' -f ( $availabilityReplicaFilestreamLevelDisabled -join ', ' ) ) + } + } + + # If the database is contained, ensure contained database authentication is enabled on all replica instances + if ( $databaseObject.ContainmentType -ne 'None' ) + { + $availabilityReplicaContainmentEnabled = @{} + foreach ( $availabilityGroupReplica in $secondaryReplicas ) + { + $connectSqlParameters = Split-FullSQLInstanceName -FullSQLInstanceName $availabilityGroupReplica.Name + $currentAvailabilityGroupReplicaServerObject = Connect-SQL @connectSqlParameters + $availabilityReplicaContainmentEnabled.Add($availabilityGroupReplica.Name, $currentAvailabilityGroupReplicaServerObject.Configuration.ContainmentEnabled.ConfigValue) + } + + if ( $availabilityReplicaContainmentEnabled.Values -notcontains 'None' ) + { + $availabilityReplicaContainmentNotEnabled = $availabilityReplicaContainmentEnabled.GetEnumerator() | Where-Object { $_.Value -eq 'None' } | Select-Object -ExpandProperty Key + $prerequisiteCheckFailures += ( 'Contained Database Authentication is not enabled on the following instances: {0}' -f ( $availabilityReplicaContainmentNotEnabled -join ', ' ) ) + } + } + + # Ensure the data and log file paths exist on all replicas + $databaseFileDirectories = @() + $databaseFileDirectories += $databaseObject.FileGroups.Files.FileName | ForEach-Object { Split-Path -Path $_ -Parent } + $databaseFileDirectories += $databaseObject.LogFiles.FileName | ForEach-Object { Split-Path -Path $_ -Parent } + $databaseFileDirectories = $databaseFileDirectories | Select-Object -Unique + + $availabilityReplicaMissingDirectories = @{} + foreach ( $availabilityGroupReplica in $secondaryReplicas ) + { + $connectSqlParameters = Split-FullSQLInstanceName -FullSQLInstanceName $availabilityGroupReplica.Name + $currentAvailabilityGroupReplicaServerObject = Connect-SQL @connectSqlParameters + + $missingDirectories = @() + foreach ( $databaseFileDirectory in $databaseFileDirectories ) + { + $fileExistsQuery = "EXEC master.dbo.xp_fileexist '$databaseFileDirectory'" + $fileExistsResult = Invoke-Query -SQLServer $currentAvailabilityGroupReplicaServerObject.NetName -SQLInstanceName $currentAvailabilityGroupReplicaServerObject.ServiceName -Database master -Query $fileExistsQuery -WithResults + + if ( $fileExistsResult.Tables.Rows.'File is a Directory' -ne 1 ) + { + $missingDirectories += $databaseFileDirectory + } + } + + if ( $missingDirectories.Count -gt 0 ) + { + $availabilityReplicaMissingDirectories.Add($availabilityGroupReplica, ( $missingDirectories -join ', ' )) + } + } + + if ( $availabilityReplicaMissingDirectories.Count -gt 0 ) + { + foreach ( $availabilityReplicaMissingDirectory in $availabilityReplicaMissingDirectories.GetEnumerator() ) + { + $prerequisiteCheckFailures += "The instance '$($availabilityReplicaMissingDirectory.Key.Name)' is missing the following directories: $($availabilityReplicaMissingDirectory.Value)" + } + } + + # If the database is TDE'd, ensure the certificate or asymmetric key is installed on all replicas + if ( $databaseObject.EncryptionEnabled ) + { + $databaseCertificateThumbprint = [System.BitConverter]::ToString($databaseObject.DatabaseEncryptionKey.Thumbprint) + $databaseCertificateName = $databaseObject.DatabaseEncryptionKey.EncryptorName + + $availabilityReplicaMissingCertificates = @{} + foreach ( $availabilityGroupReplica in $secondaryReplicas ) + { + $connectSqlParameters = Split-FullSQLInstanceName -FullSQLInstanceName $availabilityGroupReplica.Name + $currentAvailabilityGroupReplicaServerObject = Connect-SQL @connectSqlParameters + [System.Array]$installedCertificateThumbprints = $currentAvailabilityGroupReplicaServerObject.Databases['master'].Certificates | ForEach-Object { [System.BitConverter]::ToString($_.Thumbprint) } + + if ( $installedCertificateThumbprints -notcontains $databaseCertificateThumbprint ) + { + $availabilityReplicaMissingCertificates.Add($availabilityGroupReplica, $databaseCertificateName) + } + } + + if ( $availabilityReplicaMissingCertificates.Count -gt 0 ) + { + foreach ( $availabilityReplicaMissingCertificate in $availabilityReplicaMissingCertificates.GetEnumerator() ) + { + $prerequisiteCheckFailures += "The instance '$($availabilityReplicaMissingCertificate.Key.Name)' is missing the following certificates: $($availabilityReplicaMissingCertificate.Value)" + } + } + } + + if ( $prerequisiteCheckFailures.Count -eq 0 ) + { + $databaseFullBackupFile = Join-Path -Path $BackupPath -ChildPath "$($databaseObject.Name)_Full_$(Get-Date -Format 'yyyyMMddhhmmss').bak" + $databaseLogBackupFile = Join-Path -Path $BackupPath -ChildPath "$($databaseObject.Name)_Log_$(Get-Date -Format 'yyyyMMddhhmmss').trn" + + # Build the backup parameters. If no backup was previously taken, a standard full will be taken. Otherwise a CopyOnly backup will be taken. + $backupSqlDatabaseParameters = @{ + DatabaseObject = $databaseObject + BackupAction = 'Database' + BackupFile = $databaseFullBackupFile + ErrorAction = 'Stop' + } + + # If no full backup was ever taken, do not take a backup with CopyOnly + if ( $databaseObject.LastBackupDate -ne 0 ) + { + $backupSqlDatabaseParameters.Add('CopyOnly', $true) + } + + try + { + Backup-SqlDatabase @backupSqlDatabaseParameters + } + catch + { + # Log the failure + $databasesToAddFailures.Add($databaseToAddToAvailabilityGroup, $_.Exception) + + # Move on to the next database + continue + } + + # Create the parameters to perform a transaction log backup + $backupSqlDatabaseLogParams = @{ + DatabaseObject = $databaseObject + BackupAction = 'Log' + BackupFile = $databaseLogBackupFile + ErrorAction = 'Stop' + } + + try + { + Backup-SqlDatabase @backupSqlDatabaseLogParams + } + catch + { + # Log the failure + $databasesToAddFailures.Add($databaseToAddToAvailabilityGroup, $_.Exception) + + # Move on to the next database + continue + } + + # Add the database to the availability group on the primary instance + try + { + Add-SqlAvailabilityDatabase -InputObject $availabilityGroup -Database $databaseToAddToAvailabilityGroup + } + catch + { + # Log the failure + $databasesToAddFailures.Add($databaseToAddToAvailabilityGroup, $_.Exception) + + # Move on to the next database + continue + } + + # Need to restore the database with a query in order to impersonate the correct login + $restoreDatabaseQueryStringBuilder = New-Object -TypeName System.Text.StringBuilder + + if ( $MatchDatabaseOwner ) + { + $restoreDatabaseQueryStringBuilder.Append('EXECUTE AS LOGIN = ''') | Out-Null + $restoreDatabaseQueryStringBuilder.Append($databaseObject.Owner) | Out-Null + $restoreDatabaseQueryStringBuilder.AppendLine('''') | Out-Null + } + + $restoreDatabaseQueryStringBuilder.Append('RESTORE DATABASE [') | Out-Null + $restoreDatabaseQueryStringBuilder.Append($databaseToAddToAvailabilityGroup) | Out-Null + $restoreDatabaseQueryStringBuilder.AppendLine(']') | Out-Null + $restoreDatabaseQueryStringBuilder.Append('FROM DISK = ''') | Out-Null + $restoreDatabaseQueryStringBuilder.Append($databaseFullBackupFile) | Out-Null + $restoreDatabaseQueryStringBuilder.AppendLine('''') | Out-Null + $restoreDatabaseQueryStringBuilder.Append('WITH NORECOVERY') | Out-Null + $restoreDatabaseQueryString = $restoreDatabaseQueryStringBuilder.ToString() + + # Build the parameters to restore the transaction log + $restoreSqlDatabaseLogParameters = @{ + Database = $databaseToAddToAvailabilityGroup + BackupFile = $databaseLogBackupFile + RestoreAction = 'Log' + NoRecovery = $true + } + + try + { + foreach ( $availabilityGroupReplica in $secondaryReplicas ) + { + # Connect to the replica + $connectSqlParameters = Split-FullSQLInstanceName -FullSQLInstanceName $availabilityGroupReplica.Name + $currentAvailabilityGroupReplicaServerObject = Connect-SQL @connectSqlParameters + $currentReplicaAvailabilityGroupObject = $currentAvailabilityGroupReplicaServerObject.AvailabilityGroups[$AvailabilityGroupName] + + # Restore the database + Invoke-Query -SQLServer $currentAvailabilityGroupReplicaServerObject.NetName -SQLInstanceName $currentAvailabilityGroupReplicaServerObject.ServiceName -Database master -Query $restoreDatabaseQueryString + Restore-SqlDatabase -InputObject $currentAvailabilityGroupReplicaServerObject @restoreSqlDatabaseLogParameters + + # Add the database to the Availability Group + Add-SqlAvailabilityDatabase -InputObject $currentReplicaAvailabilityGroupObject -Database $databaseToAddToAvailabilityGroup + } + } + catch + { + # Log the failure + $databasesToAddFailures.Add($databaseToAddToAvailabilityGroup, $_.Exception) + + # Move on to the next database + continue + } + finally + { + # Clean up the backup files + Remove-Item -Path $databaseFullBackupFile, $databaseLogBackupFile -Force -ErrorAction Continue + } + } + else + { + $databasesToAddFailures.Add($databaseToAddToAvailabilityGroup, "The following prerequisite checks failed: $( $prerequisiteCheckFailures -join "`r`n" )" ) + } + } + } + + if ( $databasesToRemoveFromAvailabilityGroup.Count -gt 0 ) + { + Write-Verbose -Message ($script:localizedData.RemovingDatabasesToAvailabilityGroup -f $AvailabilityGroupName, ( $databasesToRemoveFromAvailabilityGroup -join ', ' )) + + foreach ( $databaseToAddToAvailabilityGroup in $databasesToRemoveFromAvailabilityGroup ) + { + $availabilityDatabase = $primaryServerObject.AvailabilityGroups[$AvailabilityGroupName].AvailabilityDatabases[$databaseToAddToAvailabilityGroup] + + try + { + Remove-SqlAvailabilityDatabase -InputObject $availabilityDatabase -ErrorAction Stop + } + catch + { + $databasesToRemoveFailures.Add($databaseToAddToAvailabilityGroup, 'Failed to remove the database from the availability group.') + } + } + } + + # Combine the failures into one error message and throw it here. Doing this will allow all the databases that can be processes to be processed and will still show that applying the configuration failed + if ( ( $databasesToAddFailures.Count -gt 0 ) -or ( $databasesToRemoveFailures.Count -gt 0 ) ) + { + $formatArgs = @() + foreach ( $failure in ( $databasesToAddFailures.GetEnumerator() + $databasesToRemoveFailures.GetEnumerator() ) ) + { + $formatArgs += "The operation on the database '$( $failure.Key )' failed with the following errors: $( $failure.Value -join "`r`n" )" + } + + throw ($script:localizedData.AlterAvailabilityGroupDatabaseMembershipFailure -f $formatArgs ) + } +} + +<# + .SYNOPSIS + Tests the database membership of the specified Availability Group. + + .PARAMETER DatabaseName + The name of the database(s) to add to the availability group. This accepts wildcards. + + .PARAMETER ServerName + Hostname of the SQL Server where the primary replica of the availability group lives. If the + availability group is not currently on this server, the resource will attempt to connect to the + server where the primary replica lives. + + .PARAMETER InstanceName + Name of the SQL instance where the primary replica of the availability group lives. If the + availability group is not currently on this instance, the resource will attempt to connect to + the instance where the primary replica lives. + + .PARAMETER AvailabilityGroupName + The name of the availability group in which to manage the database membership(s). + + .PARAMETER BackupPath + The path used to seed the availability group replicas. This should be a path that is accessible + by all of the replicas. + + .PARAMETER Ensure + Specifies the membership of the database(s) in the availability group. The options are: + + - Present: The defined database(s) are added to the availability group. All other + databases that may be a member of the availability group are ignored. + - Absent: The defined database(s) are removed from the availability group. All other + databases that may be a member of the availability group are ignored. + + The default is 'Present'. + + .PARAMETER Force + When used with "Ensure = 'Present'" it ensures the specified database(s) are the only databases + that are a member of the specified Availability Group. + + This parameter is ignored when 'Ensure' is 'Absent'. + + .PARAMETER MatchDatabaseOwner + If set to $true, this ensures the database owner of the database on the primary replica is the + owner of the database on all secondary replicas. This requires the database owner is available + as a login on all replicas and that the PSDscRunAsCredential has impersonate permissions. + + If set to $false, the owner of the database will be the PSDscRunAsCredential. + + The default is '$true'. + + .PARAMETER ProcessOnlyOnActiveNode + Specifies that the resource will only determine if a change is needed if the target node is the active host of the SQL Server Instance. +#> +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [System.String[]] + $DatabaseName, + + [Parameter(Mandatory = $true)] + [System.String] + $ServerName, + + [Parameter(Mandatory = $true)] + [System.String] + $InstanceName, + + [Parameter(Mandatory = $true)] + [System.String] + $AvailabilityGroupName, + + [Parameter(Mandatory = $true)] + [System.String] + $BackupPath, + + [Parameter()] + [ValidateSet('Present', 'Absent')] + [System.String] + $Ensure = 'Present', + + [Parameter()] + [System.Boolean] + $Force, + + [Parameter()] + [System.Boolean] + $MatchDatabaseOwner, + + [Parameter()] + [System.Boolean] + $ProcessOnlyOnActiveNode + ) + + $configurationInDesiredState = $true + + $getTargetResourceParameters = @{ + DatabaseName = $DatabaseName + ServerName = $ServerName + InstanceName = $InstanceName + AvailabilityGroupName = $AvailabilityGroupName + BackupPath = $BackupPath + } + $currentConfiguration = Get-TargetResource @getTargetResourceParameters + + <# + If this is supposed to process only the active node, and this is not the + active node, don't bother evaluating the test. + #> + if ( $ProcessOnlyOnActiveNode -and -not $currentConfiguration.IsActiveNode ) + { + Write-Verbose -Message ( $script:localizedData.NotActiveNode -f $env:COMPUTERNAME,$InstanceName ) + return $configurationInDesiredState + } + + # Connect to the defined instance + $serverObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName + + # Get the Availability Group if it exists + if ( -not [System.String]::IsNullOrEmpty($currentConfiguration.AvailabilityGroupName) ) + { + $availabilityGroup = $serverObject.AvailabilityGroups[$AvailabilityGroupName] + + # Make sure we're communicating with the primary replica in order to make changes to the replica + $primaryServerObject = Get-PrimaryReplicaServerObject -ServerObject $serverObject -AvailabilityGroup $availabilityGroup + + $matchingDatabaseNames = Get-MatchingDatabaseNames -DatabaseName $DatabaseName -ServerObject $primaryServerObject + $databasesNotFoundOnTheInstance = @() + + if ( ( $Ensure -eq 'Present' ) -and $matchingDatabaseNames.Count -eq 0 ) + { + $configurationInDesiredState = $false + Write-Verbose -Message ($script:localizedData.DatabasesNotFound -f ($DatabaseName -join ', ')) + } + else + { + $databasesNotFoundOnTheInstance = Get-DatabaseNamesNotFoundOnTheInstance -DatabaseName $DatabaseName -MatchingDatabaseNames $matchingDatabaseNames + + # If the databases specified are not present on the instance and the desired state is not Absent + if ( ( $databasesNotFoundOnTheInstance.Count -gt 0 ) -and ( $Ensure -ne 'Absent' ) ) + { + $configurationInDesiredState = $false + Write-Verbose -Message ($script:localizedData.DatabasesNotFound -f ( $databasesNotFoundOnTheInstance -join ', ' )) + } + + $getDatabasesToAddToAvailabilityGroupParameters = @{ + DatabaseName = $DatabaseName + Ensure = $Ensure + ServerObject = $primaryServerObject + AvailabilityGroup = $availabilityGroup + } + $databasesToAddToAvailabilityGroup = Get-DatabasesToAddToAvailabilityGroup @getDatabasesToAddToAvailabilityGroupParameters + + if ( $databasesToAddToAvailabilityGroup.Count -gt 0 ) + { + $configurationInDesiredState = $false + Write-Verbose -Message ($script:localizedData.DatabaseShouldBeMember -f $AvailabilityGroupName, ( $databasesToAddToAvailabilityGroup -join ', ' )) + } + + $getDatabasesToRemoveFromAvailabilityGroupParameters = @{ + DatabaseName = $DatabaseName + Ensure = $Ensure + Force = $Force + ServerObject = $primaryServerObject + AvailabilityGroup = $availabilityGroup + } + $databasesToRemoveFromAvailabilityGroup = Get-DatabasesToRemoveFromAvailabilityGroup @getDatabasesToRemoveFromAvailabilityGroupParameters + + if ( $databasesToRemoveFromAvailabilityGroup.Count -gt 0 ) + { + $configurationInDesiredState = $false + Write-Verbose -Message ($script:localizedData.DatabaseShouldNotBeMember -f $AvailabilityGroupName, ( $databasesToRemoveFromAvailabilityGroup -join ', ' )) + } + } + } + else + { + $configurationInDesiredState = $false + Write-Verbose -Message ($script:localizedData.AvailabilityGroupDoesNotExist -f ($DatabaseName -join ', ')) + } + + return $configurationInDesiredState +} + +<# + .SYNOPSIS + Get the databases that should be members of the Availability Group. + + .PARAMETER DatabaseName + The name of the database(s) to add to the availability group. This accepts wildcards. + + .PARAMETER Ensure + Specifies the membership of the database(s) in the availability group. The options are: + + - Present: The defined database(s) are added to the availability group. All other + databases that may be a member of the availability group are ignored. + - Absent: The defined database(s) are removed from the availability group. All other + databases that may be a member of the availability group are ignored. + + .PARAMETER ServerObject + The server object the databases should be in. + + .PARAMETER AvailabilityGroup + The availability group object the databases should be a member of. +#> +function Get-DatabasesToAddToAvailabilityGroup +{ + [CmdletBinding()] + param + ( + [Parameter()] + [System.String[]] + $DatabaseName, + + [Parameter(Mandatory = $true)] + [System.String] + $Ensure, + + [Parameter(Mandatory = $true)] + [Microsoft.SqlServer.Management.Smo.Server] + $ServerObject, + + [Parameter(Mandatory = $true)] + [Microsoft.SqlServer.Management.Smo.AvailabilityGroup] + $AvailabilityGroup + ) + + $matchingDatabaseNames = Get-MatchingDatabaseNames -DatabaseName $DatabaseName -ServerObject $ServerObject + + # This is a hack to allow Compare-Object to work on an empty object + if ( $null -eq $matchingDatabaseNames ) + { + $MatchingDatabaseNames = @('') + } + + $databasesInAvailabilityGroup = $AvailabilityGroup.AvailabilityDatabases | Select-Object -ExpandProperty Name + + # This is a hack to allow Compare-Object to work on an empty object + if ( $null -eq $databasesInAvailabilityGroup ) + { + $databasesInAvailabilityGroup = @('') + } + + $comparisonResult = Compare-Object -ReferenceObject $matchingDatabaseNames -DifferenceObject $databasesInAvailabilityGroup + $databasesToAddToAvailabilityGroup = @() + + if ( $Ensure -eq 'Present' ) + { + $databasesToAddToAvailabilityGroup = $comparisonResult | Where-Object -FilterScript { $_.SideIndicator -eq '<=' } | Select-Object -ExpandProperty InputObject + } + + return $databasesToAddToAvailabilityGroup +} + +<# + .SYNOPSIS + Get the databases that should not be members of the Availability Group. + + .PARAMETER DatabaseName + The name of the database(s) to add to the availability group. This accepts wildcards. + + .PARAMETER Ensure + Specifies the membership of the database(s) in the availability group. The options are: + + - Present: The defined database(s) are added to the availability group. All other + databases that may be a member of the availability group are ignored. + - Absent: The defined database(s) are removed from the availability group. All other + databases that may be a member of the availability group are ignored. + + .PARAMETER Force + When used with "Ensure = 'Present'" it ensures the specified database(s) are the only databases + that are a member of the specified Availability Group. + + This parameter is ignored when 'Ensure' is 'Absent'. + + .PARAMETER ServerObject + The server object the databases should not be in. + + .PARAMETER AvailabilityGroup + The availability group object the databases should not be a member of. +#> +function Get-DatabasesToRemoveFromAvailabilityGroup +{ + [CmdletBinding()] + param + ( + [Parameter()] + [System.String[]] + $DatabaseName, + + [Parameter(Mandatory = $true)] + [System.String] + $Ensure, + + [Parameter()] + [System.Boolean] + $Force, + + [Parameter(Mandatory = $true)] + [Microsoft.SqlServer.Management.Smo.Server] + $ServerObject, + + [Parameter(Mandatory = $true)] + [Microsoft.SqlServer.Management.Smo.AvailabilityGroup] + $AvailabilityGroup + ) + + $matchingDatabaseNames = Get-MatchingDatabaseNames -DatabaseName $DatabaseName -ServerObject $ServerObject + + + if ( $null -eq $matchingDatabaseNames ) + { + $MatchingDatabaseNames = @('') + } + + $databasesInAvailabilityGroup = $AvailabilityGroup.AvailabilityDatabases | Select-Object -ExpandProperty Name + + # This is a hack to allow Compare-Object to work on an empty object + if ( $null -eq $databasesInAvailabilityGroup ) + { + $databasesInAvailabilityGroup = @('') + } + + $comparisonResult = Compare-Object -ReferenceObject $matchingDatabaseNames -DifferenceObject $databasesInAvailabilityGroup -IncludeEqual + + $databasesToRemoveFromAvailabilityGroup = @() + + if ( 'Absent' -eq $Ensure ) + { + $databasesToRemoveFromAvailabilityGroup = $comparisonResult | Where-Object -FilterScript { '==' -eq $_.SideIndicator } | Select-Object -ExpandProperty InputObject + } + elseif ( ( 'Present' -eq $Ensure ) -and ( $Force ) ) + { + $databasesToRemoveFromAvailabilityGroup = $comparisonResult | Where-Object -FilterScript { '=>' -eq $_.SideIndicator } | Select-Object -ExpandProperty InputObject + } + + return $databasesToRemoveFromAvailabilityGroup +} + +<# + .SYNOPSIS + Get the database names that were specified in the configuration that do not exist on the instance. + + .PARAMETER DatabaseName + The name of the database(s) to add to the availability group. This accepts wildcards. + + .PARAMETER MatchingDatabaseNames + All of the databases names that match the supplied names and wildcards. +#> +function Get-MatchingDatabaseNames +{ + [CmdletBinding()] + param + ( + [Parameter()] + [System.String[]] + $DatabaseName, + + [Parameter(Mandatory = $true)] + [Microsoft.SqlServer.Management.Smo.Server] + $ServerObject + ) + + $matchingDatabaseNames = @() + + foreach ( $dbName in $DatabaseName ) + { + $matchingDatabaseNames += $ServerObject.Databases | + Where-Object -FilterScript { $_.Name -ilike $dbName } | + Select-Object -ExpandProperty Name + } + + return $matchingDatabaseNames +} + +<# + .SYNOPSIS + Get the database names that were defined in the DatabaseName property but were not found on the instance. + + .PARAMETER DatabaseName + The name of the database(s) to add to the availability group. This accepts wildcards. + + .PARAMETER MatchingDatabaseNames + All of the database names that were found on the instance that match the supplied DatabaseName property. +#> +function Get-DatabaseNamesNotFoundOnTheInstance +{ + [CmdletBinding()] + param + ( + [Parameter()] + [System.String[]] + $DatabaseName, + + [Parameter()] + [System.String[]] + $MatchingDatabaseNames + ) + + $databasesNotFoundOnTheInstance = @{} + foreach ( $dbName in $DatabaseName ) + { + # Assume the database name was not found + $databaseToAddToAvailabilityGroupNotFound = $true + + foreach ( $matchingDatabaseName in $matchingDatabaseNames ) + { + if ( $matchingDatabaseName -like $dbName ) + { + # If we found the database name, it's not missing + $databaseToAddToAvailabilityGroupNotFound = $false + } + } + + $databasesNotFoundOnTheInstance.Add($dbName, $databaseToAddToAvailabilityGroupNotFound) + } + + $result = $databasesNotFoundOnTheInstance.GetEnumerator() | Where-Object -FilterScript { $_.Value } | Select-Object -ExpandProperty Key + + return $result +} diff --git a/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAGDatabase/MSFT_SqlAGDatabase.schema.mof b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAGDatabase/MSFT_SqlAGDatabase.schema.mof new file mode 100644 index 000000000..1a9628f19 --- /dev/null +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAGDatabase/MSFT_SqlAGDatabase.schema.mof @@ -0,0 +1,14 @@ +[ClassVersion("1.0.0.0"), FriendlyName("SqlAGDatabase")] +class MSFT_SqlAGDatabase : OMI_BaseResource +{ + [Required, Description("The name of the database(s) to add to the availability group. This accepts wildcards.")] String DatabaseName[]; + [Key, Description("Hostname of the SQL Server where the primary replica of the availability group lives. If the availability group is not currently on this server, the resource will attempt to connect to the server where the primary replica lives.")] String ServerName; + [Key, Description("Name of the SQL instance to be configured.")] String InstanceName; + [Key, Description("The name of the availability group in which to manage the database membership(s).")] String AvailabilityGroupName; + [Required, Description("The path used to seed the availability group replicas. This should be a path that is accessible by all of the replicas")] String BackupPath; + [Write, Description("Specifies the membership of the database(s) in the availability group. The options are: Present: The defined database(s) are added to the availability group. All other databases that may be a member of the availability group are ignored. Absent: The defined database(s) are removed from the availability group. All other databases that may be a member of the availability group are ignored. The default is 'Present'."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; + [Write, Description("When used with 'Ensure = 'Present'' it ensures the specified database(s) are the only databases that are a member of the specified Availability Group. This parameter is ignored when 'Ensure' is 'Absent'.")] Boolean Force; + [Write, Description("If set to $true, this ensures the database owner of the database on the primary replica is the owner of the database on all secondary replicas. This requires the database owner is available as a login on all replicas and that the PSDscRunAsAccount has impersonate permissions. If set to $false, the owner of the database will be the PSDscRunAsAccount. The default is '$true'")] Boolean MatchDatabaseOwner; + [Write, Description("Specifies that the resource will only determine if a change is needed if the target node is the active host of the SQL Server Instance.")] Boolean ProcessOnlyOnActiveNode; + [Read, Description("Determines if the current node is actively hosting the SQL Server instance.")] Boolean IsActiveNode; +}; diff --git a/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAGDatabase/en-US/MSFT_SqlAGDatabase.strings.psd1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAGDatabase/en-US/MSFT_SqlAGDatabase.strings.psd1 new file mode 100644 index 000000000..112cf9e1e --- /dev/null +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAGDatabase/en-US/MSFT_SqlAGDatabase.strings.psd1 @@ -0,0 +1,15 @@ +# Localized resources for SqlAGDatabase + +ConvertFrom-StringData @' + AddingDatabasesToAvailabilityGroup = Adding the following databases to the '{0}' availability group: {1}. + AlterAvailabilityGroupDatabaseMembershipFailure = {0}. + AvailabilityGroupDoesNotExist = The availability group '{0}' does not exist. + DatabaseShouldBeMember = The following databases should be a member of the availability group '{0}': {1}. + DatabaseShouldNotBeMember = The following databases should not be a member of the availability group '{0}': {1}. + DatabasesNotFound = The following databases were not found in the instance: {0}. + ImpersonatePermissionsMissing = The login '{0}' is missing impersonate permissions in the instances '{1}'. + NotActiveNode = The node '{0}' is not actively hosting the instance '{1}'. Exiting the test. + ParameterNotOfType = The parameter '{0}' is not of the type '{1}'. + ParameterNullOrEmpty = The parameter '{0}' is NULL or empty. + RemovingDatabasesToAvailabilityGroup = Removing the following databases from the '{0}' availability group: {1}. +'@ diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAvailabilityGroupListener/MSFT_xSQLServerAvailabilityGroupListener.psm1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAGListener/MSFT_SqlAGListener.psm1 similarity index 84% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAvailabilityGroupListener/MSFT_xSQLServerAvailabilityGroupListener.psm1 rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAGListener/MSFT_SqlAGListener.psm1 index 87933a802..f9bd1f682 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAvailabilityGroupListener/MSFT_xSQLServerAvailabilityGroupListener.psm1 +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAGListener/MSFT_SqlAGListener.psm1 @@ -1,14 +1,14 @@ -Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) ` - -ChildPath 'xSQLServerHelper.psm1') ` - -Force +Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) ` + -ChildPath 'SqlServerDscHelper.psm1') ` + -Force <# .SYNOPSIS - Returns the current state of the Availabilty Group listener. + Returns the current state of the Availability Group listener. .PARAMETER InstanceName The SQL Server instance name of the primary replica. Default value is 'MSSQLSERVER'. - .PARAMETER NodeName + .PARAMETER ServerName The host name or FQDN of the primary replica. .PARAMETER Name @@ -29,10 +29,10 @@ function Get-TargetResource [Parameter(Mandatory = $true)] [System.String] - $NodeName, + $ServerName, [Parameter(Mandatory = $true)] - [ValidateLength(1,15)] + [ValidateLength(1, 15)] [System.String] $Name, @@ -43,7 +43,7 @@ function Get-TargetResource try { - $availabilityGroupListener = Get-SQLAlwaysOnAvailabilityGroupListener -Name $Name -AvailabilityGroup $AvailabilityGroup -NodeName $NodeName -InstanceName $InstanceName + $availabilityGroupListener = Get-SQLAlwaysOnAvailabilityGroupListener -Name $Name -AvailabilityGroup $AvailabilityGroup -ServerName $ServerName -InstanceName $InstanceName if ($null -ne $availabilityGroupListener) { @@ -77,14 +77,14 @@ function Get-TargetResource } return @{ - InstanceName = [System.String] $InstanceName - NodeName = [System.String] $NodeName - Name = [System.String] $Name - Ensure = [System.String] $ensure + InstanceName = [System.String] $InstanceName + ServerName = [System.String] $ServerName + Name = [System.String] $Name + Ensure = [System.String] $ensure AvailabilityGroup = [System.String] $AvailabilityGroup - IpAddress = [System.String[]] $ipAddress - Port = [System.UInt16] $port - DHCP = [System.Boolean] $dhcp + IpAddress = [System.String[]] $ipAddress + Port = [System.UInt16] $port + DHCP = [System.Boolean] $dhcp } } @@ -95,7 +95,7 @@ function Get-TargetResource .PARAMETER InstanceName The SQL Server instance name of the primary replica. Default value is 'MSSQLSERVER'. - .PARAMETER NodeName + .PARAMETER ServerName The host name or FQDN of the primary replica. .PARAMETER Name @@ -108,7 +108,7 @@ function Get-TargetResource The name of the availability group to which the availability group listener is or will be connected. .PARAMETER IpAddress - The IP address used for the availability group listener, in the format 192.168.10.45/255.255.252.0. If using DCHP, set to the first IP-address of the DHCP subnet, in the format 192.168.8.1/255.255.252.0. Must be valid in the cluster-allowed IP range. + The IP address used for the availability group listener, in the format 192.168.10.45/255.255.252.0. If using DHCP, set to the first IP-address of the DHCP subnet, in the format 192.168.8.1/255.255.252.0. Must be valid in the cluster-allowed IP range. .PARAMETER Port The port used for the availability group listener. @@ -127,14 +127,15 @@ function Set-TargetResource [Parameter(Mandatory = $true)] [System.String] - $NodeName, + $ServerName, [Parameter(Mandatory = $true)] - [ValidateLength(1,15)] + [ValidateLength(1, 15)] [System.String] $Name, - [ValidateSet('Present','Absent')] + [Parameter()] + [ValidateSet('Present', 'Absent')] [System.String] $Ensure = 'Present', @@ -142,20 +143,23 @@ function Set-TargetResource [System.String] $AvailabilityGroup, + [Parameter()] [System.String[]] $IpAddress, + [Parameter()] [System.UInt16] $Port, + [Parameter()] [System.Boolean] $DHCP ) $parameters = @{ - InstanceName = [System.String] $InstanceName - NodeName = [System.String] $NodeName - Name = [System.String] $Name + InstanceName = [System.String] $InstanceName + ServerName = [System.String] $ServerName + Name = [System.String] $Name AvailabilityGroup = [System.String] $AvailabilityGroup } @@ -168,13 +172,13 @@ function Set-TargetResource { New-VerboseMessage -Message "Create listener on $AvailabilityGroup" - $sqlServerObject = Connect-SQL -SQLServer $NodeName -SQLInstanceName $InstanceName + $sqlServerObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName $availabilityGroupObject = $sqlServerObject.AvailabilityGroups[$AvailabilityGroup] if ($availabilityGroupObject) { $newListenerParams = @{ - Name = $Name + Name = $Name InputObject = $availabilityGroupObject } @@ -190,7 +194,7 @@ function Set-TargetResource { New-VerboseMessage -Message "Listener set to DHCP with subnet $IpAddress" $newListenerParams += @{ - DhcpSubnet = [string]$IpAddress + DhcpSubnet = [System.String] $IpAddress } } elseif (-not $DHCP -and $IpAddress.Count -gt 0) @@ -209,14 +213,14 @@ function Set-TargetResource } else { - throw New-TerminatingError -ErrorType AvailabilityGroupNotFound -FormatArgs @($AvailabilityGroup,$InstanceName) -ErrorCategory ObjectNotFound + throw New-TerminatingError -ErrorType AvailabilityGroupNotFound -FormatArgs @($AvailabilityGroup, $InstanceName) -ErrorCategory ObjectNotFound } } else { New-VerboseMessage -Message "Remove listener from $AvailabilityGroup" - $sqlServerObject = Connect-SQL -SQLServer $NodeName -SQLInstanceName $InstanceName + $sqlServerObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName $availabilityGroupObject = $sqlServerObject.AvailabilityGroups[$AvailabilityGroup] if ($availabilityGroupObject) @@ -233,7 +237,7 @@ function Set-TargetResource } else { - throw New-TerminatingError -ErrorType AvailabilityGroupNotFound -FormatArgs @($AvailabilityGroup,$InstanceName) -ErrorCategory ObjectNotFound + throw New-TerminatingError -ErrorType AvailabilityGroupNotFound -FormatArgs @($AvailabilityGroup, $InstanceName) -ErrorCategory ObjectNotFound } } } @@ -256,11 +260,11 @@ function Set-TargetResource # No new IP-address if ($null -eq $IpAddress -or -not ( Compare-Object -ReferenceObject $IpAddress -DifferenceObject $availabilityGroupListenerState.IpAddress)) { - $ipAddressEqual = $true + $ipAddressEqual = $true } else { - throw New-TerminatingError -ErrorType AvailabilityGroupListenerIPChangeError -FormatArgs @($($IpAddress -join ', '),$($availabilityGroupListenerState.IpAddress -join ', ')) -ErrorCategory InvalidOperation + throw New-TerminatingError -ErrorType AvailabilityGroupListenerIPChangeError -FormatArgs @($($IpAddress -join ', '), $($availabilityGroupListenerState.IpAddress -join ', ')) -ErrorCategory InvalidOperation } } @@ -269,7 +273,7 @@ function Set-TargetResource throw New-TerminatingError -ErrorType AvailabilityGroupListenerDHCPChangeError -FormatArgs @( $DHCP, $($availabilityGroupListenerState.DHCP) ) -ErrorCategory InvalidOperation } - $sqlServerObject = Connect-SQL -SQLServer $NodeName -SQLInstanceName $InstanceName + $sqlServerObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName $availabilityGroupObject = $sqlServerObject.AvailabilityGroups[$AvailabilityGroup] if ($availabilityGroupObject) @@ -287,7 +291,7 @@ function Set-TargetResource $setListenerParams = @{ InputObject = $availabilityGroupListenerObject - Port = $Port + Port = $Port } Set-SqlAvailabilityGroupListener @setListenerParams -ErrorAction Stop | Out-Null @@ -309,7 +313,7 @@ function Set-TargetResource $setListenerParams = @{ InputObject = $availabilityGroupListenerObject - StaticIp = $newIpAddress + StaticIp = $newIpAddress } Add-SqlAvailabilityGroupListenerStaticIp @setListenerParams -ErrorAction Stop | Out-Null @@ -327,7 +331,7 @@ function Set-TargetResource } else { - throw New-TerminatingError -ErrorType AvailabilityGroupNotFound -FormatArgs @($AvailabilityGroup,$InstanceName) -ErrorCategory ObjectNotFound + throw New-TerminatingError -ErrorType AvailabilityGroupNotFound -FormatArgs @($AvailabilityGroup, $InstanceName) -ErrorCategory ObjectNotFound } } } @@ -345,7 +349,7 @@ function Set-TargetResource .PARAMETER InstanceName The SQL Server instance name of the primary replica. Default value is 'MSSQLSERVER'. - .PARAMETER NodeName + .PARAMETER ServerName The host name or FQDN of the primary replica. .PARAMETER Name @@ -358,7 +362,7 @@ function Set-TargetResource The name of the availability group to which the availability group listener is or will be connected. .PARAMETER IpAddress - The IP address used for the availability group listener, in the format 192.168.10.45/255.255.252.0. If using DCHP, set to the first IP-address of the DHCP subnet, in the format 192.168.8.1/255.255.252.0. Must be valid in the cluster-allowed IP range. + The IP address used for the availability group listener, in the format 192.168.10.45/255.255.252.0. If using DHCP, set to the first IP-address of the DHCP subnet, in the format 192.168.8.1/255.255.252.0. Must be valid in the cluster-allowed IP range. .PARAMETER Port The port used for the availability group listener. @@ -378,14 +382,15 @@ function Test-TargetResource [Parameter(Mandatory = $true)] [System.String] - $NodeName, + $ServerName, [Parameter(Mandatory = $true)] - [ValidateLength(1,15)] + [ValidateLength(1, 15)] [System.String] $Name, - [ValidateSet('Present','Absent')] + [Parameter()] + [ValidateSet('Present', 'Absent')] [System.String] $Ensure = 'Present', @@ -393,20 +398,23 @@ function Test-TargetResource [System.String] $AvailabilityGroup, + [Parameter()] [System.String[]] $IpAddress, + [Parameter()] [System.UInt16] $Port, + [Parameter()] [System.Boolean] $DHCP ) $parameters = @{ - InstanceName = [System.String] $InstanceName - NodeName = [System.String] $NodeName - Name = [System.String] $Name + InstanceName = [System.String] $InstanceName + ServerName = [System.String] $ServerName + Name = [System.String] $Name AvailabilityGroup = [System.String] $AvailabilityGroup } @@ -471,12 +479,12 @@ function Get-SQLAlwaysOnAvailabilityGroupListener [Parameter(Mandatory = $true)] [System.String] - $NodeName + $ServerName ) Write-Debug "Connecting to availability group $Name as $([System.Security.Principal.WindowsIdentity]::GetCurrent().Name)" - $sqlServerObject = Connect-SQL -SQLServer $NodeName -SQLInstanceName $InstanceName + $sqlServerObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName $availabilityGroupObject = $sqlServerObject.AvailabilityGroups[$AvailabilityGroup] if ($availabilityGroupObject) @@ -485,7 +493,7 @@ function Get-SQLAlwaysOnAvailabilityGroupListener } else { - throw New-TerminatingError -ErrorType AvailabilityGroupNotFound -FormatArgs @($AvailabilityGroup,$InstanceName) -ErrorCategory ObjectNotFound + throw New-TerminatingError -ErrorType AvailabilityGroupNotFound -FormatArgs @($AvailabilityGroup, $InstanceName) -ErrorCategory ObjectNotFound } return $availabilityGroupListener diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAvailabilityGroupListener/MSFT_xSQLServerAvailabilityGroupListener.schema.mof b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAGListener/MSFT_SqlAGListener.schema.mof similarity index 82% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAvailabilityGroupListener/MSFT_xSQLServerAvailabilityGroupListener.schema.mof rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAGListener/MSFT_SqlAGListener.schema.mof index 41b7db592..781c88df1 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAvailabilityGroupListener/MSFT_xSQLServerAvailabilityGroupListener.schema.mof +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAGListener/MSFT_SqlAGListener.schema.mof @@ -1,13 +1,13 @@ -[ClassVersion("1.0.0.0"), FriendlyName("xSQLServerAvailabilityGroupListener")] -class MSFT_xSQLServerAvailabilityGroupListener : OMI_BaseResource +[ClassVersion("1.0.0.0"), FriendlyName("SqlAGListener")] +class MSFT_SqlAGListener : OMI_BaseResource { [Key, Description("The SQL Server instance name of the primary replica.")] String InstanceName; - [Required, Description("The host name or FQDN of the primary replica.")] String NodeName; + [Required, Description("The host name or FQDN of the primary replica.")] String ServerName; [Required, Description("The name of the availability group listener, max 15 characters. This name will be used as the Virtual Computer Object (VCO).")] String Name; [Write, Description("If the availability group listener should be present or absent. Default value is 'Present'."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; [Key, Description("The name of the availability group to which the availability group listener is or will be connected.")] String AvailabilityGroup; - [Write, Description("The IP address used for the availability group listener, in the format 192.168.10.45/255.255.252.0. If using DCHP, set to the first IP-address of the DHCP subnet, in the format 192.168.8.1/255.255.252.0. Must be valid in the cluster-allowed IP range.")] String IpAddress[]; + [Write, Description("The IP address used for the availability group listener, in the format 192.168.10.45/255.255.252.0. If using DHCP, set to the first IP-address of the DHCP subnet, in the format 192.168.8.1/255.255.252.0. Must be valid in the cluster-allowed IP range.")] String IpAddress[]; [Write, Description("The port used for the availability group listener")] UInt16 Port; [Write, Description("If DHCP should be used for the availability group listener instead of static IP address.")] Boolean DHCP; }; diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAlwaysOnAvailabilityGroupReplica/MSFT_xSQLServerAlwaysOnAvailabilityGroupReplica.psm1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAGReplica/MSFT_SqlAGReplica.psm1 similarity index 69% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAlwaysOnAvailabilityGroupReplica/MSFT_xSQLServerAlwaysOnAvailabilityGroupReplica.psm1 rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAGReplica/MSFT_SqlAGReplica.psm1 index 982164cd8..fb0fc0c2a 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAlwaysOnAvailabilityGroupReplica/MSFT_xSQLServerAlwaysOnAvailabilityGroupReplica.psm1 +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAGReplica/MSFT_SqlAGReplica.psm1 @@ -1,50 +1,54 @@ Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) ` - -ChildPath 'xSQLServerHelper.psm1') ` - -Force + -ChildPath 'SqlServerDscHelper.psm1') ` + -Force <# .SYNOPSIS - Gets the specified Availabilty Group Replica from the specified Availabilty Group. - + Gets the specified Availability Group Replica from the specified Availability Group. + .PARAMETER Name - The name of the availability group replica. + The name of the availability group replica. For named instances this + must be in the following format ServerName\InstanceName. .PARAMETER AvailabilityGroupName The name of the availability group. - .PARAMETER SQLServer + .PARAMETER ServerName Hostname of the SQL Server to be configured. - - .PARAMETER SQLInstanceName - Name of the SQL instance to be configued. + + .PARAMETER InstanceName + Name of the SQL instance to be configured. #> function Get-TargetResource { [CmdletBinding()] - [OutputType([Hashtable])] + [OutputType([System.Collections.Hashtable])] param ( [Parameter(Mandatory = $true)] - [String] + [System.String] $Name, [Parameter(Mandatory = $true)] - [String] + [System.String] $AvailabilityGroupName, - + [Parameter(Mandatory = $true)] - [String] - $SQLServer, - + [System.String] + $ServerName, + [Parameter(Mandatory = $true)] - [String] - $SQLInstanceName + [System.String] + $InstanceName ) - + # Connect to the instance - $serverObject = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName + $serverObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName - # Get the endpoint properties + # Is this node actively hosting the SQL instance? + $isActiveNode = Test-ActiveNode -ServerObject $serverObject + + # Get the endpoint properties $endpoint = $serverObject.Endpoints | Where-Object { $_.EndpointType -eq 'DatabaseMirroring' } if ( $endpoint ) { @@ -53,31 +57,32 @@ function Get-TargetResource # Create the return object $alwaysOnAvailabilityGroupReplicaResource = @{ - Ensure = 'Absent' - Name = '' - AvailabilityGroupName = '' - AvailabilityMode = '' - BackupPriority = '' - ConnectionModeInPrimaryRole = '' + Ensure = 'Absent' + Name = '' + AvailabilityGroupName = '' + AvailabilityMode = '' + BackupPriority = '' + ConnectionModeInPrimaryRole = '' ConnectionModeInSecondaryRole = '' - FailoverMode = '' - EndpointUrl = '' - ReadOnlyRoutingConnectionUrl = '' - ReadOnlyRoutingList = @() - SQLServer = $SQLServer - SQLInstanceName = $SQLInstanceName - EndpointPort = $endpointPort - SQLServerNetName = $serverObject.NetName + FailoverMode = '' + EndpointUrl = '' + IsActiveNode = $isActiveNode + ReadOnlyRoutingConnectionUrl = '' + ReadOnlyRoutingList = @() + ServerName = $ServerName + InstanceName = $InstanceName + EndpointPort = $endpointPort + EndpointHostName = $serverObject.NetName } # Get the availability group $availabilityGroup = $serverObject.AvailabilityGroups[$AvailabilityGroupName] - + if ( $availabilityGroup ) { # Add the Availability Group name to the results $alwaysOnAvailabilityGroupReplicaResource.AvailabilityGroupName = $availabilityGroup.Name - + # Try to find the replica $availabilityGroupReplica = $availabilityGroup.AvailabilityReplicas[$Name] @@ -103,23 +108,24 @@ function Get-TargetResource <# .SYNOPSIS Creates or removes the availability group replica in accordance with the desired state. - + .PARAMETER Name - The name of the availability group replica. + The name of the availability group replica. For named instances this + must be in the following format ServerName\InstanceName. .PARAMETER AvailabilityGroupName The name of the availability group. - .PARAMETER SQLServer + .PARAMETER ServerName Hostname of the SQL Server to be configured. - - .PARAMETER SQLInstanceName - Name of the SQL instance to be configued. - .PARAMETER PrimaryReplicaSQLServer + .PARAMETER InstanceName + Name of the SQL instance to be configured. + + .PARAMETER PrimaryReplicaServerName Hostname of the SQL Server where the primary replica is expected to be active. If the primary replica is not found here, the resource will attempt to find the host that holds the primary replica and connect to it. - - .PARAMETER PrimaryReplicaSQLInstanceName + + .PARAMETER PrimaryReplicaInstanceName Name of the SQL instance where the primary replica lives. .PARAMETER Ensure @@ -142,12 +148,16 @@ function Get-TargetResource .PARAMETER FailoverMode Specifies the failover mode. Default is Manual. - + .PARAMETER ReadOnlyRoutingConnectionUrl Specifies the fully-qualified domain name (FQDN) and port to use when routing to the replica for read only connections. .PARAMETER ReadOnlyRoutingList Specifies an ordered list of replica server names that represent the probe sequence for connection director to use when redirecting read-only connections through this availability replica. This parameter applies if the availability replica is the current primary replica of the availability group. + + .PARAMETER ProcessOnlyOnActiveNode + Specifies that the resource will only determine if a change is needed if the target node is the active host of the SQL Server Instance. + Not used in Set-TargetResource. #> function Set-TargetResource { @@ -155,84 +165,88 @@ function Set-TargetResource Param ( [Parameter(Mandatory = $true)] - [String] + [System.String] $Name, [Parameter(Mandatory = $true)] - [String] + [System.String] $AvailabilityGroupName, - + [Parameter(Mandatory = $true)] - [String] - $SQLServer, + [System.String] + $ServerName, [Parameter(Mandatory = $true)] - [String] - $SQLInstanceName, + [System.String] + $InstanceName, [Parameter()] - [String] - $PrimaryReplicaSQLServer, + [System.String] + $PrimaryReplicaServerName, [Parameter()] - [String] - $PrimaryReplicaSQLInstanceName, + [System.String] + $PrimaryReplicaInstanceName, [Parameter()] - [ValidateSet('Present','Absent')] - [String] + [ValidateSet('Present', 'Absent')] + [System.String] $Ensure = 'Present', [Parameter()] - [ValidateSet('AsynchronousCommit','SynchronousCommit')] - [String] + [ValidateSet('AsynchronousCommit', 'SynchronousCommit')] + [System.String] $AvailabilityMode = 'AsynchronousCommit', [Parameter()] - [ValidateRange(0,100)] - [UInt32] + [ValidateRange(0, 100)] + [System.UInt32] $BackupPriority = 50, [Parameter()] - [ValidateSet('AllowAllConnections','AllowReadWriteConnections')] - [String] + [ValidateSet('AllowAllConnections', 'AllowReadWriteConnections')] + [System.String] $ConnectionModeInPrimaryRole, [Parameter()] - [ValidateSet('AllowNoConnections','AllowReadIntentConnectionsOnly','AllowAllConnections')] - [String] + [ValidateSet('AllowNoConnections', 'AllowReadIntentConnectionsOnly', 'AllowAllConnections')] + [System.String] $ConnectionModeInSecondaryRole, [Parameter()] - [String] + [System.String] $EndpointHostName, [Parameter()] - [ValidateSet('Automatic','Manual')] - [String] + [ValidateSet('Automatic', 'Manual')] + [System.String] $FailoverMode = 'Manual', [Parameter()] - [String] + [System.String] $ReadOnlyRoutingConnectionUrl, [Parameter()] - [String[]] - $ReadOnlyRoutingList + [System.String[]] + $ReadOnlyRoutingList, + + [Parameter()] + [System.Boolean] + $ProcessOnlyOnActiveNode ) - + Import-SQLPSModule - + # Connect to the instance - $serverObject = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName + $serverObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName # Determine if HADR is enabled on the instance. If not, throw an error if ( -not $serverObject.IsHadrEnabled ) { - throw New-TerminatingError -ErrorType HadrNotEnabled -FormatArgs $Ensure,$SQLInstanceName -ErrorCategory NotImplemented + throw New-TerminatingError -ErrorType HadrNotEnabled -FormatArgs $Ensure, $InstanceName -ErrorCategory NotImplemented } - # Get the Availabilty Group if it exists + # Get the Availability Group if it exists $availabilityGroup = $serverObject.AvailabilityGroups[$AvailabilityGroupName] # Make sure we're communicating with the primary replica in order to make changes to the replica @@ -240,7 +254,7 @@ function Set-TargetResource { while ( $availabilityGroup.LocalReplicaRole -ne 'Primary' ) { - $primaryServerObject = Connect-SQL -SQLServer $availabilityGroup.PrimaryReplicaServerName + $primaryServerObject = Get-PrimaryReplicaServerObject -ServerObject $serverObject -AvailabilityGroup $availabilityGroup $availabilityGroup = $primaryServerObject.AvailabilityGroups[$AvailabilityGroupName] } } @@ -261,7 +275,7 @@ function Set-TargetResource } catch { - throw New-TerminatingError -ErrorType RemoveAvailabilityGroupReplicaFailed -FormatArgs $Name, $_.Exception -ErrorCategory ResourceUnavailable + throw New-TerminatingError -ErrorType RemoveAvailabilityGroupReplicaFailed -FormatArgs $Name -ErrorCategory ResourceUnavailable -InnerException $_.Exception } } } @@ -269,68 +283,14 @@ function Set-TargetResource Present { - $clusterServiceName = 'NT SERVICE\ClusSvc' - $ntAuthoritySystemName = 'NT AUTHORITY\SYSTEM' - $availabilityGroupManagementPerms = @('Connect SQL','Alter Any Availability Group','View Server State') - $clusterPermissionsPresent = $false - - foreach ( $loginName in @( $clusterServiceName, $ntAuthoritySystemName ) ) - { - if ( $serverObject.Logins[$loginName] -and -not $clusterPermissionsPresent ) - { - $testLoginEffectivePermissionsParams = @{ - SQLServer = $SQLServer - SQLInstanceName = $SQLInstanceName - LoginName = $loginName - Permissions = $availabilityGroupManagementPerms - } - - $clusterPermissionsPresent = Test-LoginEffectivePermissions @testLoginEffectivePermissionsParams - - if ( -not $clusterPermissionsPresent ) - { - switch ( $loginName ) - { - $clusterServiceName - { - New-VerboseMessage -Message "The recommended account '$loginName' is missing one or more of the following permissions: $( $availabilityGroupManagementPerms -join ', ' ). Trying with '$ntAuthoritySystemName'." - } - - $ntAuthoritySystemName - { - New-VerboseMessage -Message "'$loginName' is missing one or more of the following permissions: $( $availabilityGroupManagementPerms -join ', ' )" - } - } - } - } - elseif ( -not $clusterPermissionsPresent ) - { - switch ( $loginName ) - { - $clusterServiceName - { - New-VerboseMessage -Message "The recommended login '$loginName' is not present. Trying with '$ntAuthoritySystemName'." - } - - $ntAuthoritySystemName - { - New-VerboseMessage -Message "The login '$loginName' is not present." - } - } - } - } - - # If neither 'NT SERVICE\ClusSvc' or 'NT AUTHORITY\SYSTEM' have the required permissions, throw an error. - if ( -not $clusterPermissionsPresent ) - { - throw New-TerminatingError -ErrorType ClusterPermissionsMissing -FormatArgs $SQLServer,$SQLInstanceName -ErrorCategory SecurityError - } + # Ensure the appropriate cluster permissions are present + Test-ClusterPermissions -ServerObject $serverObject # Make sure a database mirroring endpoint exists. $endpoint = $serverObject.Endpoints | Where-Object { $_.EndpointType -eq 'DatabaseMirroring' } if ( -not $endpoint ) { - throw New-TerminatingError -ErrorType DatabaseMirroringEndpointNotFound -FormatArgs $SQLServer,$SQLInstanceName -ErrorCategory ObjectNotFound + throw New-TerminatingError -ErrorType DatabaseMirroringEndpointNotFound -FormatArgs $ServerName, $InstanceName -ErrorCategory ObjectNotFound } # If a hostname for the endpoint was not specified, define it now. @@ -341,11 +301,11 @@ function Set-TargetResource # Get the endpoint port $endpointPort = $endpoint.Protocol.Tcp.ListenerPort - - # Determine if the Availabilty Group exists on the instance + + # Determine if the Availability Group exists on the instance if ( $availabilityGroup ) - { - # Make sure the replia exists on the instance. If the availability group exists, the replica should exist. + { + # Make sure the replica exists on the instance. If the availability group exists, the replica should exist. $availabilityGroupReplica = $availabilityGroup.AvailabilityReplicas[$Name] if ( $availabilityGroupReplica ) { @@ -362,39 +322,39 @@ function Set-TargetResource } # Make sure ConnectionModeInPrimaryRole has a value in order to avoid false positive matches when the parameter is not defined - if ( ( -not [string]::IsNullOrEmpty($ConnectionModeInPrimaryRole) ) -and ( $ConnectionModeInPrimaryRole -ne $availabilityGroupReplica.ConnectionModeInPrimaryRole ) ) + if ( ( -not [System.String]::IsNullOrEmpty($ConnectionModeInPrimaryRole) ) -and ( $ConnectionModeInPrimaryRole -ne $availabilityGroupReplica.ConnectionModeInPrimaryRole ) ) { $availabilityGroupReplica.ConnectionModeInPrimaryRole = $ConnectionModeInPrimaryRole Update-AvailabilityGroupReplica -AvailabilityGroupReplica $availabilityGroupReplica } # Make sure ConnectionModeInSecondaryRole has a value in order to avoid false positive matches when the parameter is not defined - if ( ( -not [string]::IsNullOrEmpty($ConnectionModeInSecondaryRole) ) -and ( $ConnectionModeInSecondaryRole -ne $availabilityGroupReplica.ConnectionModeInSecondaryRole ) ) + if ( ( -not [System.String]::IsNullOrEmpty($ConnectionModeInSecondaryRole) ) -and ( $ConnectionModeInSecondaryRole -ne $availabilityGroupReplica.ConnectionModeInSecondaryRole ) ) { $availabilityGroupReplica.ConnectionModeInSecondaryRole = $ConnectionModeInSecondaryRole Update-AvailabilityGroupReplica -AvailabilityGroupReplica $availabilityGroupReplica } # Break out the EndpointUrl properties - $currentEndpointProtocol, $currentEndpointHostName, $currentEndpointPort = $availabilityGroupReplica.EndpointUrl.Replace('//','').Split(':') + $currentEndpointProtocol, $currentEndpointHostName, $currentEndpointPort = $availabilityGroupReplica.EndpointUrl.Replace('//', '').Split(':') if ( $endpoint.Protocol.Tcp.ListenerPort -ne $currentEndpointPort ) { - $newEndpointUrl = $availabilityGroupReplica.EndpointUrl.Replace($currentEndpointPort,$endpoint.Protocol.Tcp.ListenerPort) + $newEndpointUrl = $availabilityGroupReplica.EndpointUrl.Replace($currentEndpointPort, $endpoint.Protocol.Tcp.ListenerPort) $availabilityGroupReplica.EndpointUrl = $newEndpointUrl Update-AvailabilityGroupReplica -AvailabilityGroupReplica $availabilityGroupReplica } if ( $EndpointHostName -ne $currentEndpointHostName ) { - $newEndpointUrl = $availabilityGroupReplica.EndpointUrl.Replace($currentEndpointHostName,$EndpointHostName) + $newEndpointUrl = $availabilityGroupReplica.EndpointUrl.Replace($currentEndpointHostName, $EndpointHostName) $availabilityGroupReplica.EndpointUrl = $newEndpointUrl Update-AvailabilityGroupReplica -AvailabilityGroupReplica $availabilityGroupReplica } if ( $currentEndpointProtocol -ne 'TCP' ) { - $newEndpointUrl = $availabilityGroupReplica.EndpointUrl.Replace($currentEndpointProtocol,'TCP') + $newEndpointUrl = $availabilityGroupReplica.EndpointUrl.Replace($currentEndpointProtocol, 'TCP') $availabilityGroupReplica.EndpointUrl = $newEndpointUrl Update-AvailabilityGroupReplica -AvailabilityGroupReplica $availabilityGroupReplica } @@ -419,64 +379,59 @@ function Set-TargetResource } else { - throw New-TerminatingError -ErrorType ReplicaNotFound -FormatArgs $Name,$SQLInstanceName -ErrorCategory ResourceUnavailable + throw New-TerminatingError -ErrorType ReplicaNotFound -FormatArgs $Name, $InstanceName -ErrorCategory ResourceUnavailable } } else { # Connect to the instance that is supposed to house the primary replica - $primaryReplicaServerObject = Connect-SQL -SQLServer $PrimaryReplicaSQLServer -SQLInstanceName $PrimaryReplicaSQLInstanceName + $primaryReplicaServerObject = Connect-SQL -SQLServer $PrimaryReplicaServerName -SQLInstanceName $PrimaryReplicaInstanceName # Verify the Availability Group exists on the supplied primary replica $primaryReplicaAvailabilityGroup = $primaryReplicaServerObject.AvailabilityGroups[$AvailabilityGroupName] if ( $primaryReplicaAvailabilityGroup ) { # Make sure the instance defined as the primary replica in the parameters is actually the primary replica - if ( $primaryReplicaAvailabilityGroup.LocalReplicaRole -ne 'Primary' ) - { - New-VerboseMessage -Message "The instance '$PrimaryReplicaSQLServer\$PrimaryReplicaSQLInstanceName' is not currently the primary replica. Connecting to '$($primaryReplicaAvailabilityGroup.PrimaryReplicaServerName)'." - - $primaryReplicaServerObject = Connect-SQL -SQLServer $primaryReplicaAvailabilityGroup.PrimaryReplicaServerName - $primaryReplicaAvailabilityGroup = $primaryReplicaServerObject.AvailabilityGroups[$AvailabilityGroupName] - } + $primaryReplicaServerObject = Get-PrimaryReplicaServerObject -ServerObject $primaryReplicaServerObject -AvailabilityGroup $primaryReplicaAvailabilityGroup + $availabilityGroup = $primaryReplicaServerObject.AvailabilityGroups[$AvailabilityGroupName] # Build the endpoint URL $endpointUrl = "TCP://$($EndpointHostName):$($endpointPort)" $newAvailabilityGroupReplicaParams = @{ - Name = $Name - InputObject = $primaryReplicaAvailabilityGroup + Name = $Name + InputObject = $primaryReplicaAvailabilityGroup AvailabilityMode = $AvailabilityMode - EndpointUrl = $endpointUrl - FailoverMode = $FailoverMode - Verbose = $false + EndpointUrl = $endpointUrl + FailoverMode = $FailoverMode + Verbose = $false } if ( $BackupPriority ) { - $newAvailabilityGroupReplicaParams.Add('BackupPriority',$BackupPriority) + $newAvailabilityGroupReplicaParams.Add('BackupPriority', $BackupPriority) } if ( $ConnectionModeInPrimaryRole ) { - $newAvailabilityGroupReplicaParams.Add('ConnectionModeInPrimaryRole',$ConnectionModeInPrimaryRole) + $newAvailabilityGroupReplicaParams.Add('ConnectionModeInPrimaryRole', $ConnectionModeInPrimaryRole) } if ( $ConnectionModeInSecondaryRole ) { - $newAvailabilityGroupReplicaParams.Add('ConnectionModeInSecondaryRole',$ConnectionModeInSecondaryRole) + $newAvailabilityGroupReplicaParams.Add('ConnectionModeInSecondaryRole', $ConnectionModeInSecondaryRole) } - + if ( $ReadOnlyRoutingConnectionUrl ) { - $newAvailabilityGroupReplicaParams.Add('ReadOnlyRoutingConnectionUrl',$ReadOnlyRoutingConnectionUrl) + $newAvailabilityGroupReplicaParams.Add('ReadOnlyRoutingConnectionUrl', $ReadOnlyRoutingConnectionUrl) } if ( $ReadOnlyRoutingList ) { - $newAvailabilityGroupReplicaParams.Add('ReadOnlyRoutingList',$ReadOnlyRoutingList) + $newAvailabilityGroupReplicaParams.Add('ReadOnlyRoutingList', $ReadOnlyRoutingList) } - + # Create the Availability Group Replica try { @@ -484,23 +439,23 @@ function Set-TargetResource } catch { - throw New-TerminatingError -ErrorType CreateAvailabilityGroupReplicaFailed -FormatArgs $Name,$SQLInstanceName -ErrorCategory OperationStopped + throw New-TerminatingError -ErrorType CreateAvailabilityGroupReplicaFailed -FormatArgs $Name, $InstanceName -ErrorCategory OperationStopped -InnerException $_.Exception } # Join the Availability Group Replica to the Availability Group try { - $joinAvailabilityGroupResults = Join-SqlAvailabilityGroup -Name $AvailabilityGroupName -InputObject $serverObject + Join-SqlAvailabilityGroup -Name $AvailabilityGroupName -InputObject $serverObject | Out-Null } catch { - throw New-TerminatingError -ErrorType JoinAvailabilityGroupFailed -FormatArgs $Name -ErrorCategory OperationStopped + throw New-TerminatingError -ErrorType JoinAvailabilityGroupFailed -FormatArgs $Name -ErrorCategory OperationStopped -InnerException $_.Exception } } # The Availability Group doesn't exist on the primary replica else { - throw New-TerminatingError -ErrorType AvailabilityGroupNotFound -FormatArgs $Name,$PrimaryReplicaSQLInstanceName -ErrorCategory ResourceUnavailable + throw New-TerminatingError -ErrorType AvailabilityGroupNotFound -FormatArgs $AvailabilityGroupName, $PrimaryReplicaInstanceName -ErrorCategory ResourceUnavailable } } } @@ -510,23 +465,24 @@ function Set-TargetResource <# .SYNOPSIS Determines if the availability group replica is in the desired state. - + .PARAMETER Name - The name of the availability group replica. + The name of the availability group replica. For named instances this + must be in the following format ServerName\InstanceName. .PARAMETER AvailabilityGroupName The name of the availability group. - .PARAMETER SQLServer + .PARAMETER ServerName Hostname of the SQL Server to be configured. - - .PARAMETER SQLInstanceName - Name of the SQL instance to be configued. - - .PARAMETER PrimaryReplicaSQLServer + + .PARAMETER InstanceName + Name of the SQL instance to be configured. + + .PARAMETER PrimaryReplicaServerName Hostname of the SQL Server where the primary replica is expected to be active. If the primary replica is not found here, the resource will attempt to find the host that holds the primary replica and connect to it. - - .PARAMETER PrimaryReplicaSQLInstanceName + + .PARAMETER PrimaryReplicaInstanceName Name of the SQL instance where the primary replica lives. .PARAMETER Ensure @@ -549,12 +505,15 @@ function Set-TargetResource .PARAMETER FailoverMode Specifies the failover mode. Default is Manual. - + .PARAMETER ReadOnlyRoutingConnectionUrl Specifies the fully-qualified domain name (FQDN) and port to use when routing to the replica for read only connections. .PARAMETER ReadOnlyRoutingList Specifies an ordered list of replica server names that represent the probe sequence for connection director to use when redirecting read-only connections through this availability replica. This parameter applies if the availability replica is the current primary replica of the availability group. + + .PARAMETER ProcessOnlyOnActiveNode + Specifies that the resource will only determine if a change is needed if the target node is the active host of the SQL Server Instance. #> function Test-TargetResource { @@ -563,84 +522,99 @@ function Test-TargetResource Param ( [Parameter(Mandatory = $true)] - [String] + [System.String] $Name, [Parameter(Mandatory = $true)] - [String] + [System.String] $AvailabilityGroupName, - + [Parameter(Mandatory = $true)] - [String] - $SQLServer, + [System.String] + $ServerName, [Parameter(Mandatory = $true)] - [String] - $SQLInstanceName, + [System.String] + $InstanceName, [Parameter()] - [String] - $PrimaryReplicaSQLServer, + [System.String] + $PrimaryReplicaServerName, [Parameter()] - [String] - $PrimaryReplicaSQLInstanceName, + [System.String] + $PrimaryReplicaInstanceName, [Parameter()] - [ValidateSet('Present','Absent')] - [String] + [ValidateSet('Present', 'Absent')] + [System.String] $Ensure = 'Present', [Parameter()] - [ValidateSet('AsynchronousCommit','SynchronousCommit')] - [String] + [ValidateSet('AsynchronousCommit', 'SynchronousCommit')] + [System.String] $AvailabilityMode = 'AsynchronousCommit', [Parameter()] - [ValidateRange(0,100)] - [UInt32] + [ValidateRange(0, 100)] + [System.UInt32] $BackupPriority = 50, [Parameter()] - [ValidateSet('AllowAllConnections','AllowReadWriteConnections')] - [String] + [ValidateSet('AllowAllConnections', 'AllowReadWriteConnections')] + [System.String] $ConnectionModeInPrimaryRole, [Parameter()] - [ValidateSet('AllowNoConnections','AllowReadIntentConnectionsOnly','AllowAllConnections')] - [String] + [ValidateSet('AllowNoConnections', 'AllowReadIntentConnectionsOnly', 'AllowAllConnections')] + [System.String] $ConnectionModeInSecondaryRole, [Parameter()] - [String] + [System.String] $EndpointHostName, [Parameter()] - [ValidateSet('Automatic','Manual')] - [String] + [ValidateSet('Automatic', 'Manual')] + [System.String] $FailoverMode = 'Manual', [Parameter()] - [String] + [System.String] $ReadOnlyRoutingConnectionUrl, [Parameter()] - [String[]] - $ReadOnlyRoutingList + [System.String[]] + $ReadOnlyRoutingList, + + [Parameter()] + [System.Boolean] + $ProcessOnlyOnActiveNode ) $getTargetResourceParameters = @{ - SQLInstanceName = $SQLInstanceName - SQLServer = $SQLServer - Name = $Name + InstanceName = $InstanceName + ServerName = $ServerName + Name = $Name AvailabilityGroupName = $AvailabilityGroupName } - + # Assume this will pass. We will determine otherwise later $result = $true $getTargetResourceResult = Get-TargetResource @getTargetResourceParameters + <# + If this is supposed to process only the active node, and this is not the + active node, don't bother evaluating the test. + #> + if ( $ProcessOnlyOnActiveNode -and -not $getTargetResourceResult.IsActiveNode ) + { + # Use localization if the resource has been converted + New-VerboseMessage -Message ( 'The node "{0}" is not actively hosting the instance "{1}". Exiting the test.' -f $env:COMPUTERNAME, $InstanceName ) + return $result + } + switch ($Ensure) { 'Absent' @@ -651,7 +625,7 @@ function Test-TargetResource } else { - $result = $false + $result = $false } } @@ -660,8 +634,8 @@ function Test-TargetResource $parametersToCheck = @( 'Name', 'AvailabilityGroupName', - 'SQLServer', - 'SQLInstanceName', + 'ServerName', + 'InstanceName', 'Ensure', 'AvailabilityMode', 'BackupPriority', @@ -671,7 +645,7 @@ function Test-TargetResource 'ReadOnlyRoutingConnectionUrl', 'ReadOnlyRoutingList' ) - + if ( $getTargetResourceResult.Ensure -eq 'Present' ) { # PsBoundParameters won't work here because it doesn't account for default values @@ -679,17 +653,17 @@ function Test-TargetResource { $parameterName = $parameter.Key $parameterValue = Get-Variable -Name $parameterName -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Value - + # Make sure we don't try to validate a common parameter if ( $parametersToCheck -contains $parameterName ) { # If the parameter is Null, a value wasn't provided - if ( -not [string]::IsNullOrEmpty($parameterValue) ) - { + if ( -not [System.String]::IsNullOrEmpty($parameterValue) ) + { if ( $getTargetResourceResult.($parameterName) -ne $parameterValue ) - { + { New-VerboseMessage -Message "'$($parameterName)' should be '$($parameterValue)' but is '$($getTargetResourceResult.($parameterName))'" - + $result = $false } } @@ -697,13 +671,13 @@ function Test-TargetResource } # Get the Endpoint URL properties - $currentEndpointProtocol, $currentEndpointHostName, $currentEndpointPort = $getTargetResourceResult.EndpointUrl.Replace('//','').Split(':') + $currentEndpointProtocol, $currentEndpointHostName, $currentEndpointPort = $getTargetResourceResult.EndpointUrl.Replace('//', '').Split(':') if ( -not $EndpointHostName ) { - $EndpointHostName = $getTargetResourceResult.SQLServerNetName + $EndpointHostName = $getTargetResourceResult.EndpointHostName } - + # Verify the hostname in the endpoint URL is correct if ( $EndpointHostName -ne $currentEndpointHostName ) { diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAlwaysOnAvailabilityGroupReplica/MSFT_xSQLServerAlwaysOnAvailabilityGroupReplica.schema.mof b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAGReplica/MSFT_SqlAGReplica.schema.mof similarity index 73% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAlwaysOnAvailabilityGroupReplica/MSFT_xSQLServerAlwaysOnAvailabilityGroupReplica.schema.mof rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAGReplica/MSFT_SqlAGReplica.schema.mof index 358c7d33a..43d1a02b9 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAlwaysOnAvailabilityGroupReplica/MSFT_xSQLServerAlwaysOnAvailabilityGroupReplica.schema.mof +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAGReplica/MSFT_SqlAGReplica.schema.mof @@ -1,12 +1,12 @@ -[ClassVersion("1.0.0.0"), FriendlyName("xSQLServerAlwaysOnAvailabilityGroupReplica")] -class MSFT_xSQLServerAlwaysOnAvailabilityGroupReplica : OMI_BaseResource +[ClassVersion("1.0.0.0"), FriendlyName("SqlAGReplica")] +class MSFT_SqlAGReplica : OMI_BaseResource { - [Key, Description("The name of the availability group replica.")] String Name; + [Key, Description("The name of the availability group replica. For named instances this must be in the following format ServerName\\InstanceName.")] String Name; [Key, Description("The name of the availability group.")] String AvailabilityGroupName; - [Required, Description("Hostname of the SQL Server to be configured.")] String SQLServer; - [Key, Description("Name of the SQL instance to be configued.")] String SQLInstanceName; - [Write, Description("Hostname of the SQL Server where the primary replica is expected to be active. If the primary replica is not found here, the resource will attempt to find the host that holds the primary replica and connect to it.")] String PrimaryReplicaSQLServer; - [Write, Description("Name of the SQL instance where the primary replica lives.")] String PrimaryReplicaSQLInstanceName; + [Required, Description("Hostname of the SQL Server to be configured.")] String ServerName; + [Key, Description("Name of the SQL instance to be configured.")] String InstanceName; + [Write, Description("Hostname of the SQL Server where the primary replica is expected to be active. If the primary replica is not found here, the resource will attempt to find the host that holds the primary replica and connect to it.")] String PrimaryReplicaServerName; + [Write, Description("Name of the SQL instance where the primary replica lives.")] String PrimaryReplicaInstanceName; [Write, Description("Specifies if the availability group replica should be present or absent. Default is Present."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; [Write, Description("Specifies the replica availability mode. Default is 'AsynchronousCommit'."), ValueMap{"AsynchronousCommit","SynchronousCommit"}, Values{"AsynchronousCommit","SynchronousCommit"}] String AvailabilityMode; [Write, Description("Specifies the desired priority of the replicas in performing backups. The acceptable values for this parameter are: integers from 0 through 100. Of the set of replicas which are online and available, the replica that has the highest priority performs the backup. Default is 50.")] UInt32 BackupPriority; @@ -15,6 +15,9 @@ class MSFT_xSQLServerAlwaysOnAvailabilityGroupReplica : OMI_BaseResource [Write, Description("Specifies the hostname or IP address of the availability group replica endpoint. Default is the instance network name which is set in the code because the value can only be determined when connected to the SQL Instance.")] String EndpointHostName; [Write, Description("Specifies the failover mode. Default is 'Manual'."), ValueMap{"Automatic","Manual"}, Values{"Automatic","Manual"}] String FailoverMode; [Write, Description("Specifies the fully-qualified domain name (FQDN) and port to use when routing to the replica for read only connections.")] String ReadOnlyRoutingConnectionUrl; - [Write, Description("Specifies an ordered list of replica server names that represent the probe sequence for connection director to use when redirecting read-only connections through this availability replica. This parameter applies if the availability replica is the current primary replica of the availability group.")] String ReadOnlyRoutingList[]; - [Read, Description("Output the NetName property from the SQL Server object. Used by Get-TargetResource")] String SqlServerNetName; + [Write, Description("Specifies an ordered list of replica server names that represent the probe sequence for connection director to use when redirecting read-only connections through this availability replica. This parameter applies if the availability replica is the current primary replica of the availability group.")] String ReadOnlyRoutingList[]; + [Write, Description("Specifies that the resource will only determine if a change is needed if the target node is the active host of the SQL Server instance.")] Boolean ProcessOnlyOnActiveNode; + [Read, Description("Output the network port the endpoint is listening on. Used by Get-TargetResource.")] Uint16 EndpointPort; + [Read, Description("Output the endpoint URL of the Availability Group Replica. Used by Get-TargetResource.")] String EndpointUrl; + [Read, Description("Determines if the current node is actively hosting the SQL Server instance.")] Boolean IsActiveNode; }; diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAlias/MSFT_xSQLServerAlias.psm1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAlias/MSFT_SqlAlias.psm1 similarity index 95% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAlias/MSFT_xSQLServerAlias.psm1 rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAlias/MSFT_SqlAlias.psm1 index 550af9078..02fc47d98 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAlias/MSFT_xSQLServerAlias.psm1 +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAlias/MSFT_SqlAlias.psm1 @@ -1,4 +1,4 @@ -Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) -ChildPath 'xSQLServerHelper.psm1') -Force +Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) -ChildPath 'SqlServerDscHelper.psm1') -Force function Get-TargetResource { @@ -10,7 +10,7 @@ function Get-TargetResource [ValidateNotNullOrEmpty()] [System.String] $Name, - + [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] @@ -34,17 +34,17 @@ function Get-TargetResource $itemValue = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo' ` -Name $Name ` -ErrorAction SilentlyContinue - + if (((Get-CimInstance -ClassName win32_OperatingSystem).OSArchitecture) -eq '64-bit') { Write-Verbose -Message "64-bit Operating System. Also get the client alias $Name from Wow6432Node" - + $isWow6432Node = $true $itemValueWow6432Node = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\MSSQLServer\Client\ConnectTo' ` -Name $Name ` -ErrorAction SilentlyContinue } - + if ((-not $isWow6432Node -and $null -ne $itemValue ) -or ` (($null -ne $itemValue -and $null -ne $itemValueWow6432Node) -and ` ($isWow6432Node -and $itemValueWow6432Node."$Name" -eq $itemValue."$Name"))) @@ -75,7 +75,7 @@ function Get-TargetResource $returnValue.PipeName = $itemConfig.ServerName } } - else + else { $returnValue.Ensure = 'Absent' } @@ -121,9 +121,9 @@ function Set-TargetResource [System.String] $Ensure = 'Present' ) - + Write-Verbose -Message "Setting the SQL Server Client Alias $Name" - + if ($Protocol -eq 'NP') { $itemValue = "DBNMPNTW,\\$ServerName\PIPE\sql\query" @@ -139,7 +139,7 @@ function Set-TargetResource } $registryPath = 'HKLM:\SOFTWARE\Microsoft\MSSQLServer\Client\ConnectTo' - $registryPathWow6432Node = 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\MSSQLServer\Client\ConnectTo' + $registryPathWow6432Node = 'HKLM:\SOFTWARE\Wow6432Node\Microsoft\MSSQLServer\Client\ConnectTo' if ($Ensure -eq 'Present') { @@ -149,7 +149,7 @@ function Set-TargetResource { if (!(Test-Path -Path $registryPath)) { - New-Item -Path $registryPath | Out-Null + New-Item -Path $registryPath -Force | Out-Null } Set-ItemProperty -Path $registryPath -Name $Name -Value $itemValue | Out-Null @@ -162,7 +162,7 @@ function Set-TargetResource { if (!(Test-Path -Path $registryPathWow6432Node)) { - New-Item -Path $registryPathWow6432Node | Out-Null + New-Item -Path $registryPathWow6432Node -Force | Out-Null } Set-ItemProperty -Path $registryPathWow6432Node -Name $Name -Value $itemValue | Out-Null @@ -173,7 +173,7 @@ function Set-TargetResource if ($Ensure -eq 'Absent') { Write-Verbose -Message "Removing the SQL Server Client Alias $Name" - + if ($PSCmdlet.ShouldProcess($Name, 'Remove the client alias')) { if (Test-Path -Path $registryPath) @@ -181,7 +181,7 @@ function Set-TargetResource Remove-ItemProperty -Path $registryPath -Name $Name } } - + # If this is a 64-bit OS then also remove from Wow6432Node if (((Get-CimInstance -ClassName win32_OperatingSystem).OSArchitecture) -eq '64-bit' ` -and (Test-Path -Path $registryPathWow6432Node)) @@ -230,7 +230,7 @@ function Test-TargetResource ) Write-Verbose -Message "Testing the SQL Server Client Alias $Name" - + $result = $false $parameters = @{ @@ -252,7 +252,7 @@ function Test-TargetResource if ($Protocol -eq $currentValues.Protocol) { - if ($Protocol -eq 'NP' -and + if ($Protocol -eq 'NP' -and $currentValues.PipeName -eq "\\$ServerName\PIPE\sql\query") { $result = $true @@ -273,8 +273,8 @@ function Test-TargetResource } } } - - if ($result) + + if ($result) { Write-Verbose -Message 'In the desired state' } diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAlias/MSFT_xSQLServerAlias.schema.mof b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAlias/MSFT_SqlAlias.schema.mof similarity index 81% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAlias/MSFT_xSQLServerAlias.schema.mof rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAlias/MSFT_SqlAlias.schema.mof index bf613ea9f..2878dc822 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAlias/MSFT_xSQLServerAlias.schema.mof +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAlias/MSFT_SqlAlias.schema.mof @@ -1,9 +1,9 @@ -[ClassVersion("1.0.0.0"), FriendlyName("xSQLServerAlias")] -class MSFT_xSQLServerAlias : OMI_BaseResource +[ClassVersion("1.0.0.0"), FriendlyName("SqlAlias")] +class MSFT_SqlAlias : OMI_BaseResource { [Key, Description("The name of Alias (e.g. svr01\\inst01).")] String Name; [Write, Description("Protocol to use when connecting. Valid values are 'TCP' or 'NP' (Named Pipes). Default value is 'TCP'."), ValueMap{"TCP","NP"}, Values{"TCP","NP"}] String Protocol; - [Key, Description("The SQL Server you are aliasing (the netbios name or FQDN).")] String ServerName; + [Key, Description("The SQL Server you are aliasing (the NetBIOS name or FQDN).")] String ServerName; [Write, Description("The TCP port SQL is listening on. Only used when protocol is set to 'TCP'. Default value is port 1433.")] UInt16 TcpPort; [Write, Description("The UseDynamicTcpPort specify that the Net-Library will determine the port dynamically. The port specified in Port number will not be used. Default value is '$false'.")] Boolean UseDynamicTcpPort; [Read, Description("Named Pipes path from the Get-TargetResource method.")] String PipeName; diff --git a/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAlwaysOnService/MSFT_SqlAlwaysOnService.psm1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAlwaysOnService/MSFT_SqlAlwaysOnService.psm1 new file mode 100644 index 000000000..efc32ee76 --- /dev/null +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAlwaysOnService/MSFT_SqlAlwaysOnService.psm1 @@ -0,0 +1,208 @@ +Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) ` + -ChildPath 'SqlServerDscHelper.psm1') ` + -Force + +<# + .SYNOPSIS + Gets the current value of the SQL Server Always On high availability and + disaster recovery (HADR) property. + + .PARAMETER Ensure + An enumerated value that describes if the SQL Server should have Always On high + availability and disaster recovery (HADR) property enabled ('Present') or + disabled ('Absent'). + + *** Not used in this function *** + + .PARAMETER ServerName + The hostname of the SQL Server to be configured. + + .PARAMETER InstanceName + The name of the SQL instance to be configured. +#> +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter(Mandatory = $true)] + [ValidateSet('Present', 'Absent')] + [System.String] + $Ensure, + + [Parameter(Mandatory = $true)] + [System.String] + $ServerName, + + [Parameter(Mandatory = $true)] + [System.String] + $InstanceName + ) + + $sqlServerObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName + + $isAlwaysOnEnabled = [System.Boolean] $sqlServerObject.IsHadrEnabled + if ($isAlwaysOnEnabled -eq $true) + { + $statusString = 'enabled' + } + elseif ($isAlwaysOnEnabled -eq $false) + { + $statusString = 'disabled' + } + + New-VerboseMessage -Message ( 'SQL Always On is {0} on "{1}\{2}".' -f $statusString, $ServerName, $InstanceName ) + + return @{ + IsHadrEnabled = $isAlwaysOnEnabled + } +} + +<# + .SYNOPSIS + Sets the current value of the SQL Server Always On high availability and disaster recovery (HADR) property. + + .PARAMETER Ensure + An enumerated value that describes if the SQL Server should have Always On high + availability and disaster recovery (HADR) property enabled ('Present') or + disabled ('Absent'). + + .PARAMETER ServerName + The hostname of the SQL Server to be configured. + + .PARAMETER InstanceName + The name of the SQL instance to be configured. + + .PARAMETER RestartTimeout + The length of time, in seconds, to wait for the service to restart. Default is 120 seconds. +#> +function Set-TargetResource +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [ValidateSet('Present', 'Absent')] + [System.String] + $Ensure, + + [Parameter(Mandatory = $true)] + [System.String] + $ServerName, + + [Parameter(Mandatory = $true)] + [System.String] + $InstanceName, + + [Parameter()] + [System.UInt32] + $RestartTimeout = 120 + ) + + # Build the instance name to allow the Enable/Disable-Always On to connect to the instance + if ($InstanceName -eq "MSSQLSERVER") + { + $serverInstance = $ServerName + } + else + { + $serverInstance = "$ServerName\$InstanceName" + } + + Import-SQLPSModule + + switch ($Ensure) + { + 'Absent' + { + # Disable Always On without restarting the services. + New-VerboseMessage -Message "Disabling Always On for the instance $serverInstance" + Disable-SqlAlwaysOn -ServerInstance $serverInstance -NoServiceRestart + } + 'Present' + { + # Enable Always On without restarting the services. + New-VerboseMessage -Message "Enabling Always On for the instance $serverInstance" + Enable-SqlAlwaysOn -ServerInstance $serverInstance -NoServiceRestart + } + } + + New-VerboseMessage -Message ( 'SQL Always On has been {0} on "{1}\{2}". Restarting the service.' -f @{Absent = 'disabled'; Present = 'enabled'}[$Ensure], $ServerName, $InstanceName ) + + # Now restart the SQL service so that all dependent services are also returned to their previous state + Restart-SqlService -SQLServer $ServerName -SQLInstanceName $InstanceName -Timeout $RestartTimeout + + # Verify always on was set + if ( -not ( Test-TargetResource @PSBoundParameters ) ) + { + throw New-TerminatingError -ErrorType AlterAlwaysOnServiceFailed -FormatArgs $Ensure, $serverInstance -ErrorCategory InvalidResult + } +} + +<# + .SYNOPSIS + Determines whether the current value of the SQL Server Always On high + availability and disaster recovery (HADR) property is properly set. + + .PARAMETER Ensure + An enumerated value that describes if the SQL Server should have Always On high + availability and disaster recovery (HADR) property enabled ('Present') or + disabled ('Absent'). + + .PARAMETER ServerName + The hostname of the SQL Server to be configured. + + .PARAMETER InstanceName + The name of the SQL instance to be configured. + + .PARAMETER RestartTimeout + The length of time, in seconds, to wait for the service to restart. Default is 120 seconds. + + *** Not used in this function *** +#> +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [ValidateSet('Present', 'Absent')] + [System.String] + $Ensure, + + [Parameter(Mandatory = $true)] + [System.String] + $ServerName, + + [Parameter(Mandatory = $true)] + [System.String] + $InstanceName, + + [Parameter()] + [System.UInt32] + $RestartTimeout = 120 + ) + + # Determine the current state of Always On + $getTargetResourceParameters = @{ + Ensure = $Ensure + ServerName = $ServerName + InstanceName = $InstanceName + } + + $state = Get-TargetResource @getTargetResourceParameters + + # Determine what the desired state of Always On is + $hadrDesiredState = @{ 'Present' = $true; 'Absent' = $false }[$Ensure] + + # Determine whether the value matches the desired state + $desiredStateMet = $state.IsHadrEnabled -eq $hadrDesiredState + + New-VerboseMessage -Message ( 'SQL Always On is in the desired state for "{0}\{1}": {2}.' -f $ServerName, $InstanceName, $desiredStateMet ) + + return $desiredStateMet +} + +Export-ModuleMember -Function *-TargetResource diff --git a/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAlwaysOnService/MSFT_SqlAlwaysOnService.schema.mof b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAlwaysOnService/MSFT_SqlAlwaysOnService.schema.mof new file mode 100644 index 000000000..337f1427d --- /dev/null +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlAlwaysOnService/MSFT_SqlAlwaysOnService.schema.mof @@ -0,0 +1,9 @@ +[ClassVersion("1.0.0.0"), FriendlyName("SqlAlwaysOnService")] +class MSFT_SqlAlwaysOnService : OMI_BaseResource +{ + [Required, Description("An enumerated value that describes if the SQL Server should have Always On high availability and disaster recovery (HADR) property enabled ('Present') or disabled ('Absent')."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; + [Key, Description("The hostname of the SQL Server to be configured.")] String ServerName; + [Key, Description("The name of the SQL instance to be configured.")] String InstanceName; + [Write, Description("The length of time, in seconds, to wait for the service to restart. Default is 120 seconds.")] UInt32 RestartTimeout; + [Read, Description("Returns the status of AlwaysOn high availability and disaster recovery (HADR).")] Boolean IsHadrEnabled; +}; diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerDatabase/MSFT_xSQLServerDatabase.psm1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabase/MSFT_SqlDatabase.psm1 similarity index 53% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerDatabase/MSFT_xSQLServerDatabase.psm1 rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabase/MSFT_SqlDatabase.psm1 index ca523ffb6..ae2333b79 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerDatabase/MSFT_xSQLServerDatabase.psm1 +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabase/MSFT_SqlDatabase.psm1 @@ -1,6 +1,6 @@ Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) ` - -ChildPath 'xSQLServerHelper.psm1') ` - -Force + -ChildPath 'SqlServerDscHelper.psm1') ` + -Force <# .SYNOPSIS This function gets the sql database. @@ -12,11 +12,15 @@ Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Pare .PARAMETER Name The name of database to be created or dropped. - .PARAMETER SQLServer + .PARAMETER ServerName The host name of the SQL Server to be configured. - .PARAMETER SQLInstanceName + .PARAMETER InstanceName The name of the SQL instance to be configured. + + .PARAMETER Collation + The name of the SQL collation to use for the new database. + Defaults to server collation. #> function Get-TargetResource @@ -26,7 +30,7 @@ function Get-TargetResource param ( [Parameter()] - [ValidateSet('Present','Absent')] + [ValidateSet('Present', 'Absent')] [ValidateNotNullOrEmpty()] [System.String] $Ensure = 'Present', @@ -39,26 +43,33 @@ function Get-TargetResource [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] - $SQLServer, + $ServerName, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] - $SQLInstanceName + $InstanceName, + + [Parameter()] + [ValidateNotNullOrEmpty()] + [System.String] + $Collation ) - $sqlServerObject = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName + $sqlServerObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName if ($sqlServerObject) { + $sqlDatabaseCollation = $sqlServerObject.Collation Write-Verbose -Message 'Getting SQL Databases' # Check database exists $sqlDatabaseObject = $sqlServerObject.Databases[$Name] - + if ($sqlDatabaseObject) { Write-Verbose -Message "SQL Database name $Name is present" $Ensure = 'Present' + $sqlDatabaseCollation = $sqlDatabaseObject.Collation } else { @@ -66,12 +77,13 @@ function Get-TargetResource $Ensure = 'Absent' } } - + $returnValue = @{ - Name = $Name - Ensure = $Ensure - SQLServer = $SQLServer - SQLInstanceName = $SQLInstanceName + Name = $Name + Ensure = $Ensure + ServerName = $ServerName + InstanceName = $InstanceName + Collation = $sqlDatabaseCollation } $returnValue @@ -87,12 +99,16 @@ function Get-TargetResource .PARAMETER Name The name of database to be created or dropped. - - .PARAMETER SQLServer + + .PARAMETER ServerName The host name of the SQL Server to be configured. - .PARAMETER SQLInstanceName + .PARAMETER InstanceName The name of the SQL instance to be configured. + + .PARAMETER Collation + The name of the SQL collation to use for the new database. + Defaults to server collation. #> function Set-TargetResource { @@ -100,7 +116,7 @@ function Set-TargetResource param ( [Parameter()] - [ValidateSet('Present','Absent')] + [ValidateSet('Present', 'Absent')] [ValidateNotNullOrEmpty()] [System.String] $Ensure = 'Present', @@ -113,56 +129,95 @@ function Set-TargetResource [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] - $SQLServer, + $ServerName, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] - $SQLInstanceName + $InstanceName, + + [Parameter()] + [ValidateNotNullOrEmpty()] + [System.String] + $Collation ) - $sqlServerObject = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName + $sqlServerObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName if ($sqlServerObject) { if ($Ensure -eq 'Present') { - try + if (-not $PSBoundParameters.ContainsKey('Collation')) { - $sqlDatabaseObjectToCreate = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Database -ArgumentList $sqlServerObject,$Name - if ($sqlDatabaseObjectToCreate) + $Collation = $sqlServerObject.Collation + } + elseif ($Collation -notin $sqlServerObject.EnumCollations().Name) + { + throw New-TerminatingError -ErrorType InvalidCollationError ` + -FormatArgs @($ServerName, $InstanceName, $Name, $Collation) ` + -ErrorCategory InvalidOperation + } + + $sqlDatabaseObject = $sqlServerObject.Databases[$Name] + + if ($sqlDatabaseObject) + { + try + { + Write-Verbose -Message "Updating the database $Name with specified settings." + $sqlDatabaseObject.Collation = $Collation + $sqlDatabaseObject.Alter() + New-VerboseMessage -Message "Updated Database $Name." + } + catch { - Write-Verbose -Message "Adding to SQL the database $Name" - $sqlDatabaseObjectToCreate.Create() - New-VerboseMessage -Message "Created Database $Name" + throw New-TerminatingError -ErrorType UpdateDatabaseSetError ` + -FormatArgs @($ServerName, $InstanceName, $Name) ` + -ErrorCategory InvalidOperation ` + -InnerException $_.Exception } } - catch + else { - throw New-TerminatingError -ErrorType CreateDatabaseSetError ` - -FormatArgs @($SQLServer,$SQLInstanceName,$Name) ` - -ErrorCategory InvalidOperation ` - -InnerException $_.Exception + try + { + $sqlDatabaseObjectToCreate = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Database -ArgumentList $sqlServerObject, $Name + if ($sqlDatabaseObjectToCreate) + { + Write-Verbose -Message "Adding to SQL the database $Name." + $sqlDatabaseObjectToCreate.Collation = $Collation + $sqlDatabaseObjectToCreate.Create() + New-VerboseMessage -Message "Created Database $Name." + } + } + catch + { + throw New-TerminatingError -ErrorType CreateDatabaseSetError ` + -FormatArgs @($ServerName, $InstanceName, $Name) ` + -ErrorCategory InvalidOperation ` + -InnerException $_.Exception + } } } else { - try + try { $sqlDatabaseObjectToDrop = $sqlServerObject.Databases[$Name] if ($sqlDatabaseObjectToDrop) { - Write-Verbose -Message "Deleting to SQL the database $Name" + Write-Verbose -Message "Deleting to SQL the database $Name." $sqlDatabaseObjectToDrop.Drop() - New-VerboseMessage -Message "Dropped Database $Name" + New-VerboseMessage -Message "Dropped Database $Name." } } catch { throw New-TerminatingError -ErrorType DropDatabaseSetError ` - -FormatArgs @($SQLServer,$SQLInstanceName,$Name) ` - -ErrorCategory InvalidOperation ` - -InnerException $_.Exception + -FormatArgs @($ServerName, $InstanceName, $Name) ` + -ErrorCategory InvalidOperation ` + -InnerException $_.Exception } } } @@ -178,12 +233,16 @@ function Set-TargetResource .PARAMETER Name The name of database to be created or dropped. - - .PARAMETER SQLServer + + .PARAMETER ServerName The host name of the SQL Server to be configured. - .PARAMETER SQLInstanceName + .PARAMETER InstanceName The name of the SQL instance to be configured. + + .PARAMETER Collation + The name of the SQL collation to use for the new database. + Defaults to server collation. #> function Test-TargetResource { @@ -192,7 +251,7 @@ function Test-TargetResource param ( [Parameter()] - [ValidateSet('Present','Absent')] + [ValidateSet('Present', 'Absent')] [ValidateNotNullOrEmpty()] [System.String] $Ensure = 'Present', @@ -205,19 +264,29 @@ function Test-TargetResource [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] - $SQLServer, + $ServerName, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] - $SQLInstanceName - ) + $InstanceName, + + [Parameter()] + [ValidateNotNullOrEmpty()] + [System.String] + $Collation + ) Write-Verbose -Message "Checking if database named $Name is present or absent" $getTargetResourceResult = Get-TargetResource @PSBoundParameters $isDatabaseInDesiredState = $true - + + if (-not $PSBoundParameters.ContainsKey('Collation')) + { + $Collation = $getTargetResourceResult.Collation + } + switch ($Ensure) { 'Absent' @@ -228,7 +297,7 @@ function Test-TargetResource $isDatabaseInDesiredState = $false } } - + 'Present' { if ($getTargetResourceResult.Ensure -ne 'Present') @@ -236,10 +305,15 @@ function Test-TargetResource New-VerboseMessage -Message "Ensure is set to Present. The database $Name should be created" $isDatabaseInDesiredState = $false } + elseif ($getTargetResourceResult.Collation -ne $Collation) + { + New-VerboseMessage -Message 'Database exist but has the wrong collation.' + $isDatabaseInDesiredState = $false + } } } - $isDatabaseInDesiredState + $isDatabaseInDesiredState } Export-ModuleMember -Function *-TargetResource diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerDatabase/MSFT_xSQLServerDatabase.schema.mof b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabase/MSFT_SqlDatabase.schema.mof similarity index 61% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerDatabase/MSFT_xSQLServerDatabase.schema.mof rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabase/MSFT_SqlDatabase.schema.mof index 442e02a02..1164ca056 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerDatabase/MSFT_xSQLServerDatabase.schema.mof +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabase/MSFT_SqlDatabase.schema.mof @@ -1,8 +1,9 @@ -[ClassVersion("1.0.0.0"), FriendlyName("xSQLServerDatabase")] -class MSFT_xSQLServerDatabase : OMI_BaseResource +[ClassVersion("1.0.0.0"), FriendlyName("SqlDatabase")] +class MSFT_SqlDatabase : OMI_BaseResource { [Key, Description("The name of the SQL database.")] String Name; [Write, Description("An enumerated value that describes if the database is added (Present) or dropped (Absent). Valid values are 'Present' or 'Absent'. Default Value is 'Present'."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; - [Key, Description("The host name of the SQL Server to be configured.")] String SQLServer; - [Key, Description("The name of the SQL instance to be configured.")] String SQLInstanceName; + [Key, Description("The host name of the SQL Server to be configured.")] String ServerName; + [Key, Description("The name of the SQL instance to be configured.")] String InstanceName; + [Write, Description("The name of the SQL collation to use for the new database. Defaults to server collation.")] String Collation; }; diff --git a/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseDefaultLocation/MSFT_SqlDatabaseDefaultLocation.psm1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseDefaultLocation/MSFT_SqlDatabaseDefaultLocation.psm1 new file mode 100644 index 000000000..c623091c8 --- /dev/null +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseDefaultLocation/MSFT_SqlDatabaseDefaultLocation.psm1 @@ -0,0 +1,292 @@ +Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) ` + -ChildPath 'SqlServerDscHelper.psm1') ` + -Force + +Import-Module -Name (Join-Path -Path (Split-Path -Path $PSScriptRoot -Parent) ` + -ChildPath 'CommonResourceHelper.psm1') + +$script:localizedData = Get-LocalizedData -ResourceName 'MSFT_SqlDatabaseDefaultLocation' + +<# + .SYNOPSIS + Returns the current path to the the desired default location for the Data, Log, or Backup files. + + .PARAMETER ServerName + The host name of the SQL Server to be configured. + + .PARAMETER InstanceName + The name of the SQL instance to be configured. + + .PARAMETER Type + The type of database default location to be configured. { Data | Log | Backup } + + .PARAMETER Path + The path to the default directory to be configured. + Not used in Get-TargetResource +#> +Function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $ServerName, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $InstanceName, + + [Parameter(Mandatory = $true)] + [ValidateSet('Data', 'Log', 'Backup')] + [System.String] + $Type, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $Path + ) + + Write-Verbose -Message ($script:localizedData.GetCurrentPath -f $Type, $InstanceName) + + # Connect to the instance + $sqlServerObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName + + # Is this node actively hosting the SQL instance? + $isActiveNode = Test-ActiveNode -ServerObject $sqlServerObject + + # Check which default location is being retrieved + switch ($Type) + { + 'Data' + { + $currentPath = $sqlServerObject.DefaultFile + } + + 'Log' + { + $currentPath = $sqlServerObject.DefaultLog + } + + 'Backup' + { + $currentPath = $sqlServerObject.BackupDirectory + } + } + + return @{ + InstanceName = $InstanceName + ServerName = $ServerName + Type = $Type + Path = $currentPath + IsActiveNode = $isActiveNode + } +} + +<# + .SYNOPSIS + This function sets the current path for the default SQL Instance location for the Data, Log, or Backups files. + + .PARAMETER ServerName + The host name of the SQL Server to be configured. + + .PARAMETER InstanceName + The name of the SQL instance to be configured. + + .PARAMETER Type + The type of database default location to be configured. { Data | Log | Backup } + + .PARAMETER Path + The path to the default directory to be configured. + + .PARAMETER RestartService + If set to $true then SQL Server and dependent services will be restarted if a change to the default location + is made. The default value is $false. + + .PARAMETER ProcessOnlyOnActiveNode + Specifies that the resource will only determine if a change is needed if the target node is the active host of the SQL Server Instance. + Not used in Set-TargetResource. +#> +Function Set-TargetResource +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $ServerName, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $InstanceName, + + [Parameter(Mandatory = $true)] + [ValidateSet('Data', 'Log', 'Backup')] + [System.String] + $Type, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $Path, + + [Parameter()] + [System.Boolean] + $RestartService = $false, + + [Parameter()] + [System.Boolean] + $ProcessOnlyOnActiveNode + ) + + # Make sure the Path exists, needs to be cluster aware as well for this check + if (-Not (Test-Path $Path)) + { + throw ($script:localizedData.InvalidPath -f $Path) + } + else + { + Write-Verbose -Message ($script:localizedData.SettingDefaultPath -f $Type) + $sqlServerObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName + + # Check which default location is being updated + switch ($Type) + { + 'Data' + { + $currentValuePath = $sqlServerObject.DefaultFile + $sqlServerObject.DefaultFile = $Path + } + + 'Log' + { + $currentValuePath = $sqlServerObject.DefaultLog + $sqlServerObject.DefaultLog = $Path + } + + 'Backup' + { + $currentValuePath = $sqlServerObject.BackupDirectory + $sqlServerObject.BackupDirectory = $Path + } + } + + # Wrap the Alter command in a try-catch in case the update doesn't work + try + { + $originalErrorActionPreference = $ErrorActionPreference + $ErrorActionPreference = 'Stop' + $sqlServerObject.Alter() + Write-Verbose -Message ($script:localizedData.DefaultPathChanged -f $Type, $currentValuePath, $Path) + + if ($RestartService) + { + Write-Verbose -Message ($script:localizedData.RestartSqlServer -f $ServerName, $InstanceName) + Restart-SqlService -SQLServer $ServerName -SQLInstanceName $InstanceName + } + } + catch + { + $errorMessage = $script:localizedData.ChangingPathFailed + New-InvalidOperationException -Message $errorMessage -ErrorRecord $_ + } + finally + { + $ErrorActionPreference = $originalErrorActionPreference + } + } +} + +<# + .SYNOPSIS + This function tests the current path to the default database location for the Data, Log, or Backups files. + + .PARAMETER ServerName + The host name of the SQL Server to be configured. + + .PARAMETER InstanceName + The name of the SQL instance to be configured. + + .PARAMETER Type + The type of database default location to be configured. { Data | Log | Backup } + + .PARAMETER Path + The path to the default directory to be configured. + + .PARAMETER RestartService + If set to $true then SQL Server and dependent services will be restarted if a change to the default location + is made. The default value is $false. + + .PARAMETER ProcessOnlyOnActiveNode + Specifies that the resource will only determine if a change is needed if the target node is the active host of the SQL Server Instance. +#> +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $ServerName, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $InstanceName, + + [Parameter(Mandatory = $true)] + [ValidateSet('Data', 'Log', 'Backup')] + [System.String] + $Type, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $Path, + + [Parameter()] + [System.Boolean] + $RestartService = $false, + + [Parameter()] + [System.Boolean] + $ProcessOnlyOnActiveNode + ) + + Write-Verbose -Message ($script:localizedData.TestingCurrentPath -f $Type) + + $getTargetResourceParameters = @{ + InstanceName = $InstanceName + ServerName = $ServerName + Type = $Type + Path = $Path + } + + $isDefaultPathInDesiredState = $true + + $getTargetResourceResult = Get-TargetResource @getTargetResourceParameters + <# + If this is supposed to process only the active node, and this is not the + active node, don't bother evaluating the test. + #> + if ( $ProcessOnlyOnActiveNode -and -not $getTargetResourceResult.IsActiveNode ) + { + Write-Verbose -Message ($script:localizedData.NotActiveClusterNode -f $env:COMPUTERNAME, $InstanceName ) + } + elseif ($getTargetResourceResult.Path -ne $Path) + { + Write-Verbose -Message ($script:localizedData.DefaultPathDifference -f $Type, $getTargetResourceResult.Path, $Path) + $isDefaultPathInDesiredState = $false + } + + return $isDefaultPathInDesiredState +} + diff --git a/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseDefaultLocation/MSFT_SqlDatabaseDefaultLocation.schema.mof b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseDefaultLocation/MSFT_SqlDatabaseDefaultLocation.schema.mof new file mode 100644 index 000000000..f49a2d941 --- /dev/null +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseDefaultLocation/MSFT_SqlDatabaseDefaultLocation.schema.mof @@ -0,0 +1,11 @@ +[ClassVersion("1.0.0.0"), FriendlyName("SqlDatabaseDefaultLocation")] +class MSFT_SqlDatabaseDefaultLocation : OMI_BaseResource +{ + [Key, Description("The host name of the SQL Server to be configured.")] String ServerName; + [Key, Description("The name of the SQL instance to be configured.")] String InstanceName; + [Key, Description("The type of database default location to be configured. { Data | Log | Backup }"), ValueMap{"Data","Log","Backup"}, Values{"Data","Log","Backup"}] String Type; + [Required, Description("The path to the default directory to be configured.")] String Path; + [Write, Description("If set to $true then SQL Server and dependent services will be restarted if a change to the default location is made. The defaul value is $false.")] Boolean RestartService; + [Write, Description("Specifies that the resource will only determine if a change is needed if the target node is the active host of the SQL Server Instance.")] Boolean ProcessOnlyOnActiveNode; + [Read, Description("Determines if the current node is actively hosting the SQL Server instance.")] Boolean IsActiveNode; +}; diff --git a/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseDefaultLocation/en-US/MSFT_SqlDatabaseDefaultLocation.strings.psd1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseDefaultLocation/en-US/MSFT_SqlDatabaseDefaultLocation.strings.psd1 new file mode 100644 index 000000000..ee9cf93cd --- /dev/null +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseDefaultLocation/en-US/MSFT_SqlDatabaseDefaultLocation.strings.psd1 @@ -0,0 +1,13 @@ +# Localized resources for MSFT_SqlDatabaseDefaultLocation + +ConvertFrom-StringData @' + GetCurrentPath = Getting default path for '{0}' for instance '{1}'. + SettingDefaultPath = Setting the default path for the '{0}' files. + DefaultPathChanged = The default path for '{0}' has been changed from '{1}' to '{2}'. + RestartSqlServer = Restarting Sql Server: {0}\\{1}. + TestingCurrentPath = Testing the default path for the '{0}' files. + DefaultPathDifference = Current default path for '{0}' is '{1}' and should be updated to '{2}'. + ChangingPathFailed = Changing the default path failed. + InvalidPath = The path '{0}' does not exist. + NotActiveClusterNode = The node '{0}' is not actively hosting the instance '{1}'. Exiting the test. +'@ diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerDatabaseOwner/MSFT_xSQLServerDatabaseOwner.psm1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseOwner/MSFT_SqlDatabaseOwner.psm1 similarity index 70% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerDatabaseOwner/MSFT_xSQLServerDatabaseOwner.psm1 rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseOwner/MSFT_SqlDatabaseOwner.psm1 index db4a63edf..fd0c03a1d 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerDatabaseOwner/MSFT_xSQLServerDatabaseOwner.psm1 +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseOwner/MSFT_SqlDatabaseOwner.psm1 @@ -1,6 +1,6 @@ Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) ` - -ChildPath 'xSQLServerHelper.psm1') ` - -Force + -ChildPath 'SqlServerDscHelper.psm1') ` + -Force <# .SYNOPSIS This function gets the owner of the desired sql database. @@ -11,10 +11,10 @@ Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Pare .PARAMETER Name The name of the login that will become a owner of the desired sql database. - .PARAMETER SQLServer + .PARAMETER ServerName The host name of the SQL Server to be configured. - .PARAMETER SQLInstanceName + .PARAMETER InstanceName The name of the SQL instance to be configured. #> function Get-TargetResource @@ -36,16 +36,16 @@ function Get-TargetResource [Parameter()] [ValidateNotNullOrEmpty()] [System.String] - $SQLServer = $env:COMPUTERNAME, + $ServerName = $env:COMPUTERNAME, [Parameter()] [ValidateNotNullOrEmpty()] [System.String] - $SQLInstanceName = 'MSSQLSERVER' + $InstanceName = 'MSSQLSERVER' ) Write-Verbose -Message "Getting owner of database $Database" - $sqlServerObject = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName + $sqlServerObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName if ($sqlServerObject) { @@ -53,8 +53,8 @@ function Get-TargetResource if ( -not ($sqlDatabaseObject = $sqlServerObject.Databases[$Database]) ) { throw New-TerminatingError -ErrorType NoDatabase ` - -FormatArgs @($Database, $SQLServer, $SQLInstanceName) ` - -ErrorCategory ObjectNotFound + -FormatArgs @($Database, $ServerName, $InstanceName) ` + -ErrorCategory ObjectNotFound } try @@ -65,16 +65,16 @@ function Get-TargetResource catch { throw New-TerminatingError -ErrorType FailedToGetOwnerDatabase ` - -FormatArgs @($Database, $SQLServer, $SQLInstanceName) ` - -ErrorCategory InvalidOperation + -FormatArgs @($Database, $ServerName, $InstanceName) ` + -ErrorCategory InvalidOperation } } $returnValue = @{ - Database = $Database - Name = $sqlDatabaseOwner - SQLServer = $SQLServer - SQLInstanceName = $SQLInstanceName + Database = $Database + Name = $sqlDatabaseOwner + ServerName = $ServerName + InstanceName = $InstanceName } $returnValue @@ -90,10 +90,10 @@ function Get-TargetResource .PARAMETER Name The name of the login that will become a owner of the desired sql database. - .PARAMETER SQLServer + .PARAMETER ServerName The host name of the SQL Server to be configured. - .PARAMETER SQLInstanceName + .PARAMETER InstanceName The name of the SQL instance to be configured. #> function Set-TargetResource @@ -114,31 +114,31 @@ function Set-TargetResource [Parameter()] [ValidateNotNullOrEmpty()] [System.String] - $SQLServer = $env:COMPUTERNAME, + $ServerName = $env:COMPUTERNAME, [Parameter()] [ValidateNotNullOrEmpty()] [System.String] - $SQLInstanceName = 'MSSQLSERVER' + $InstanceName = 'MSSQLSERVER' ) Write-Verbose -Message "Setting owner $Name of database $Database" - $sqlServerObject = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName + $sqlServerObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName - if($sqlServerObject) + if ($sqlServerObject) { # Check database exists if ( -not ($sqlDatabaseObject = $sqlServerObject.Databases[$Database]) ) { - throw New-TerminatingError -ErrorType NoDatabase -FormatArgs @($Database, $SQLServer, $SQLInstanceName) -ErrorCategory ObjectNotFound + throw New-TerminatingError -ErrorType NoDatabase -FormatArgs @($Database, $ServerName, $InstanceName) -ErrorCategory ObjectNotFound } # Check login exists if ( -not ($sqlServerObject.Logins[$Name]) ) { - throw New-TerminatingError -ErrorType LoginNotFound -FormatArgs @($Name, $SQLServer, $SQLInstanceName) -ErrorCategory ObjectNotFound + throw New-TerminatingError -ErrorType LoginNotFound -FormatArgs @($Name, $ServerName, $InstanceName) -ErrorCategory ObjectNotFound } - + try { $sqlDatabaseObject.SetOwner($Name) @@ -147,9 +147,9 @@ function Set-TargetResource catch { throw New-TerminatingError -ErrorType FailedToSetOwnerDatabase ` - -FormatArgs @($Name, $Database, $SQLServer, $SQLInstanceName) ` - -ErrorCategory InvalidOperation ` - -InnerException $_.Exception + -FormatArgs @($Name, $Database, $ServerName, $InstanceName) ` + -ErrorCategory InvalidOperation ` + -InnerException $_.Exception } } } @@ -164,10 +164,10 @@ function Set-TargetResource .PARAMETER Name The name of the login that will become a owner of the desired sql database. - .PARAMETER SQLServer + .PARAMETER ServerName The host name of the SQL Server to be configured. - .PARAMETER SQLInstanceName + .PARAMETER InstanceName The name of the SQL instance to be configured. #> function Test-TargetResource @@ -189,20 +189,20 @@ function Test-TargetResource [Parameter()] [ValidateNotNullOrEmpty()] [System.String] - $SQLServer = $env:COMPUTERNAME, + $ServerName = $env:COMPUTERNAME, [Parameter()] [ValidateNotNullOrEmpty()] [System.String] - $SQLInstanceName = 'MSSQLSERVER' + $InstanceName = 'MSSQLSERVER' ) Write-Verbose -Message "Testing owner $Name of database $Database" - + $currentValues = Get-TargetResource @PSBoundParameters return Test-SQLDscParameterState -CurrentValues $CurrentValues ` - -DesiredValues $PSBoundParameters ` - -ValuesToCheck @('Name', 'Database') + -DesiredValues $PSBoundParameters ` + -ValuesToCheck @('Name', 'Database') } Export-ModuleMember -Function *-TargetResource diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerDatabaseOwner/MSFT_xSQLServerDatabaseOwner.schema.mof b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseOwner/MSFT_SqlDatabaseOwner.schema.mof similarity index 64% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerDatabaseOwner/MSFT_xSQLServerDatabaseOwner.schema.mof rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseOwner/MSFT_SqlDatabaseOwner.schema.mof index 552d22629..c488b2e42 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerDatabaseOwner/MSFT_xSQLServerDatabaseOwner.schema.mof +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseOwner/MSFT_SqlDatabaseOwner.schema.mof @@ -1,8 +1,8 @@ -[ClassVersion("1.0.0.0"), FriendlyName("xSQLServerDatabaseOwner")] -class MSFT_xSQLServerDatabaseOwner : OMI_BaseResource +[ClassVersion("1.0.0.0"), FriendlyName("SqlDatabaseOwner")] +class MSFT_SqlDatabaseOwner : OMI_BaseResource { [Key, Description("The name of database to be configured.")] String Database; [Required, Description("The name of the login that will become a owner of the desired sql database.")] String Name; - [Write, Description("The host name of the SQL Server to be configured.")] String SQLServer; - [Write, Description("The name of the SQL instance to be configured.")] String SQLInstanceName; + [Write, Description("The host name of the SQL Server to be configured.")] String ServerName; + [Write, Description("The name of the SQL instance to be configured.")] String InstanceName; }; diff --git a/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabasePermission/MSFT_SqlDatabasePermission.psm1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabasePermission/MSFT_SqlDatabasePermission.psm1 new file mode 100644 index 000000000..3cbb9981a --- /dev/null +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabasePermission/MSFT_SqlDatabasePermission.psm1 @@ -0,0 +1,410 @@ +Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) ` + -ChildPath 'SqlServerDscHelper.psm1') ` + -Force +<# + .SYNOPSIS + Returns the current permissions for the user in the database + + .PARAMETER Database + This is the SQL database + + .PARAMETER Name + This is the name of the SQL login for the permission set + + .PARAMETER PermissionState + This is the state of permission set. Valid values are 'Grant' or 'Deny' + + .PARAMETER Permissions + This is a list that represents a SQL Server set of database permissions + + .PARAMETER ServerName + This is the SQL Server for the database + + .PARAMETER InstanceName + This is the SQL instance for the database +#> +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $Database, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $Name, + + [Parameter(Mandatory = $true)] + [ValidateSet('Grant', 'Deny', 'GrantWithGrant')] + [System.String] + $PermissionState, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String[]] + $Permissions, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $ServerName, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $InstanceName + ) + + $sqlServerObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName + + if ($sqlServerObject) + { + Write-Verbose -Message "Getting permissions for user $Name in database $Database" + $currentEnsure = 'Absent' + + if ($sqlDatabaseObject = $sqlServerObject.Databases[$Database]) + { + if ($sqlServerObject.Logins[$Name]) + { + # Initialize variable permission + [System.String[]] $getSqlDatabasePermissionResult = @() + + try + { + $databasePermissionInfo = $sqlDatabaseObject.EnumDatabasePermissions($Name) | Where-Object -FilterScript { + $_.PermissionState -eq $PermissionState + } + + foreach ($currentDatabasePermissionInfo in $databasePermissionInfo) + { + $permissionProperty = ($currentDatabasePermissionInfo.PermissionType | Get-Member -MemberType Property).Name + + foreach ($currentPermissionProperty in $permissionProperty) + { + if ($currentDatabasePermissionInfo.PermissionType."$currentPermissionProperty") + { + $getSqlDatabasePermissionResult += $currentPermissionProperty + } + } + } + } + catch + { + throw New-TerminatingError -ErrorType FailedToEnumDatabasePermissions ` + -FormatArgs @($Name, $Database, $ServerName, $InstanceName) ` + -ErrorCategory InvalidOperation ` + -InnerException $_.Exception + } + + } + else + { + throw New-TerminatingError -ErrorType LoginNotFound ` + -FormatArgs @($Name, $ServerName, $InstanceName) ` + -ErrorCategory ObjectNotFound ` + -InnerException $_.Exception + } + } + else + { + throw New-TerminatingError -ErrorType NoDatabase ` + -FormatArgs @($Database, $ServerName, $InstanceName) ` + -ErrorCategory InvalidResult ` + -InnerException $_.Exception + } + + if ($getSqlDatabasePermissionResult) + { + $resultOfPermissionCompare = Compare-Object -ReferenceObject $Permissions ` + -DifferenceObject $getSqlDatabasePermissionResult + if ($null -eq $resultOfPermissionCompare) + { + $currentEnsure = 'Present' + } + } + } + + $returnValue = @{ + Ensure = $currentEnsure + Database = $Database + Name = $Name + PermissionState = $PermissionState + Permissions = $getSqlDatabasePermissionResult + ServerName = $ServerName + InstanceName = $InstanceName + } + + $returnValue +} + +<# + .SYNOPSIS + Sets the permissions for the user in the database. + + .PARAMETER Ensure + This is The Ensure if the permission should be granted (Present) or revoked (Absent) + + .PARAMETER Database + This is the SQL database + + .PARAMETER Name + This is the name of the SQL login for the permission set + + .PARAMETER PermissionState + This is the state of permission set. Valid values are 'Grant' or 'Deny' + + .PARAMETER Permissions + This is a list that represents a SQL Server set of database permissions + + .PARAMETER ServerName + This is the SQL Server for the database + + .PARAMETER InstanceName + This is the SQL instance for the database +#> +function Set-TargetResource +{ + [CmdletBinding()] + param + ( + [Parameter()] + [ValidateSet('Present', 'Absent')] + [System.String] + $Ensure, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $Database, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $Name, + + [Parameter(Mandatory = $true)] + [ValidateSet('Grant', 'Deny', 'GrantWithGrant')] + [System.String] + $PermissionState, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String[]] + $Permissions, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $ServerName = $env:COMPUTERNAME, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $InstanceName = 'MSSQLSERVER' + ) + + $sqlServerObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName + + if ($sqlServerObject) + { + Write-Verbose -Message "Setting permissions of database $Database for login $Name" + + if ($sqlDatabaseObject = $sqlServerObject.Databases[$Database]) + { + if ($sqlServerObject.Logins[$Name]) + { + if ( -not ($sqlDatabaseObject.Users[$Name])) + { + try + { + New-VerboseMessage -Message "Adding SQL login $Name as a user of database $Database" + $sqlDatabaseUser = New-Object -TypeName Microsoft.SqlServer.Management.Smo.User -ArgumentList ($sqlDatabaseObject, $Name) + $sqlDatabaseUser.Login = $Name + $sqlDatabaseUser.Create() + } + catch + { + throw New-TerminatingError -ErrorType AddLoginDatabaseSetError ` + -FormatArgs @($ServerName, $InstanceName, $Name, $Database) ` + -ErrorCategory InvalidOperation ` + -InnerException $_.Exception + } + } + + if ($sqlDatabaseObject.Users[$Name]) + { + try + { + $permissionSet = New-Object -TypeName Microsoft.SqlServer.Management.Smo.DatabasePermissionSet + + foreach ($permission in $permissions) + { + $permissionSet."$permission" = $true + } + + switch ($Ensure) + { + 'Present' + { + New-VerboseMessage -Message ('{0} the permissions ''{1}'' to the database {2} on the server {3}\{4}' ` + -f $PermissionState, ($Permissions -join ','), $Database, $ServerName, $InstanceName) + + switch ($PermissionState) + { + 'GrantWithGrant' + { + $sqlDatabaseObject.Grant($permissionSet, $Name, $true) + } + + 'Grant' + { + $sqlDatabaseObject.Grant($permissionSet, $Name) + } + + 'Deny' + { + $sqlDatabaseObject.Deny($permissionSet, $Name) + } + } + } + + 'Absent' + { + New-VerboseMessage -Message ('Revoking {0} permissions {1} to the database {2} on the server {3}\{4}' ` + -f $PermissionState, ($Permissions -join ','), $Database, $ServerName, $InstanceName) + + if ($PermissionState -eq 'GrantWithGrant') + { + $sqlDatabaseObject.Revoke($permissionSet, $Name, $false, $true) + } + else + { + $sqlDatabaseObject.Revoke($permissionSet, $Name) + } + } + } + } + catch + { + throw New-TerminatingError -ErrorType FailedToSetPermissionDatabase ` + -FormatArgs @($Name, $Database, $ServerName, $InstanceName) ` + -ErrorCategory InvalidOperation ` + -InnerException $_.Exception + } + } + } + else + { + throw New-TerminatingError -ErrorType LoginNotFound ` + -FormatArgs @($Name, $ServerName, $InstanceName) ` + -ErrorCategory ObjectNotFound ` + -InnerException $_.Exception + } + } + else + { + throw New-TerminatingError -ErrorType NoDatabase ` + -FormatArgs @($Database, $ServerName, $InstanceName) ` + -ErrorCategory InvalidResult ` + -InnerException $_.Exception + } + } +} + +<# + .SYNOPSIS + Tests if the permissions is set for the user in the database + + .PARAMETER Ensure + This is The Ensure if the permission should be granted (Present) or revoked (Absent) + + .PARAMETER Database + This is the SQL database + + .PARAMETER Name + This is the name of the SQL login for the permission set + + .PARAMETER PermissionState + This is the state of permission set. Valid values are 'Grant' or 'Deny' + + .PARAMETER Permissions + This is a list that represents a SQL Server set of database permissions + + .PARAMETER ServerName + This is the SQL Server for the database + + .PARAMETER InstanceName + This is the SQL instance for the database +#> +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter()] + [ValidateSet('Present', 'Absent')] + [System.String] + $Ensure, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $Database, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $Name, + + [Parameter(Mandatory = $true)] + [ValidateSet('Grant', 'Deny', 'GrantWithGrant')] + [System.String] + $PermissionState, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String[]] + $Permissions, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $ServerName = $env:COMPUTERNAME, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $InstanceName = 'MSSQLSERVER' + ) + + Write-Verbose -Message "Testing permissions for user $Name in database $Database." + $getTargetResourceParameters = @{ + InstanceName = $PSBoundParameters.InstanceName + ServerName = $PSBoundParameters.ServerName + Database = $PSBoundParameters.Database + Name = $PSBoundParameters.Name + PermissionState = $PSBoundParameters.PermissionState + Permissions = $PSBoundParameters.Permissions + } + + $getTargetResourceResult = Get-TargetResource @getTargetResourceParameters + + <# + There is no need to evaluate the parameter Permissions here. + In the Get-TargetResource function there is a test to verify if Permissions is in + desired state. If the permissions are correct, then Get-TargetResource will return + the value 'Present' for the Ensure parameter, otherwise Ensure will have the value + 'Absent'. + #> + return Test-SQLDscParameterState -CurrentValues $getTargetResourceResult ` + -DesiredValues $PSBoundParameters ` + -ValuesToCheck @('Name', 'Ensure', 'PermissionState') +} + +Export-ModuleMember -Function *-TargetResource diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerDatabasePermission/MSFT_xSQLServerDatabasePermission.schema.mof b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabasePermission/MSFT_SqlDatabasePermission.schema.mof similarity index 67% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerDatabasePermission/MSFT_xSQLServerDatabasePermission.schema.mof rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabasePermission/MSFT_SqlDatabasePermission.schema.mof index 5d58b58a1..8b4fe7c04 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerDatabasePermission/MSFT_xSQLServerDatabasePermission.schema.mof +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabasePermission/MSFT_SqlDatabasePermission.schema.mof @@ -1,11 +1,11 @@ -[ClassVersion("1.0.0.0"), FriendlyName("xSQLServerDatabasePermission")] -class MSFT_xSQLServerDatabasePermission : OMI_BaseResource +[ClassVersion("1.0.0.0"), FriendlyName("SqlDatabasePermission")] +class MSFT_SqlDatabasePermission : OMI_BaseResource { [Write, Description("If the values should be present or absent. Valid values are 'Present' or 'Absent'."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; [Key, Description("The name of the database.")] String Database; [Key, Description("The name of the user that should be granted or denied the permission.")] String Name; - [Key, Description("The state of the permission. Valid values are 'Grant' or 'Deny'."), ValueMap{"Grant","Deny"}, Values{"Grant","Deny"}] String PermissionState; + [Key, Description("The state of the permission. Valid values are 'Grant' or 'Deny'."), ValueMap{"Grant","Deny","GrantWithGrant"}, Values{"Grant","Deny","GrantWithGrant"}] String PermissionState; [Required, Description("The set of permissions for the SQL database.")] String Permissions[]; - [Key, Description("The host name of the SQL Server to be configured.")] String SQLServer; - [Key, Description("The name of the SQL instance to be configured.")] String SQLInstanceName; + [Key, Description("The host name of the SQL Server to be configured.")] String ServerName; + [Key, Description("The name of the SQL instance to be configured.")] String InstanceName; }; diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerDatabaseRecoveryModel/MSFT_xSQLServerDatabaseRecoveryModel.psm1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseRecoveryModel/MSFT_SqlDatabaseRecoveryModel.psm1 similarity index 73% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerDatabaseRecoveryModel/MSFT_xSQLServerDatabaseRecoveryModel.psm1 rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseRecoveryModel/MSFT_SqlDatabaseRecoveryModel.psm1 index 0c377d6bc..651504f47 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerDatabaseRecoveryModel/MSFT_xSQLServerDatabaseRecoveryModel.psm1 +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseRecoveryModel/MSFT_SqlDatabaseRecoveryModel.psm1 @@ -1,6 +1,6 @@ Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) ` - -ChildPath 'xSQLServerHelper.psm1') ` - -Force + -ChildPath 'SqlServerDscHelper.psm1') ` + -Force <# .SYNOPSIS This function gets all Key properties defined in the resource schema file @@ -11,10 +11,10 @@ Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Pare .PARAMETER RecoveryModel This is the RecoveryModel of the SQL database - .PARAMETER SQLServer + .PARAMETER ServerName This is a the SQL Server for the database - .PARAMETER SQLInstanceName + .PARAMETER InstanceName This is a the SQL instance for the database #> function Get-TargetResource @@ -24,7 +24,7 @@ function Get-TargetResource param ( [Parameter(Mandatory = $true)] - [ValidateSet('Full','Simple','BulkLogged')] + [ValidateSet('Full', 'Simple', 'BulkLogged')] [ValidateNotNullOrEmpty()] [System.String] $RecoveryModel, @@ -32,12 +32,12 @@ function Get-TargetResource [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] - $SQLServer, + $ServerName, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] - $SQLInstanceName, + $InstanceName, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] @@ -45,13 +45,13 @@ function Get-TargetResource $Name ) - $sqlServerObject = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName + $sqlServerObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName if ($sqlServerObject) { Write-Verbose -Message "Getting RecoveryModel of SQL database '$Name'" $sqlDatabaseObject = $sqlServerObject.Databases[$Name] - + if ($sqlDatabaseObject) { $sqlDatabaseRecoveryModel = $sqlDatabaseObject.RecoveryModel @@ -60,16 +60,16 @@ function Get-TargetResource else { throw New-TerminatingError -ErrorType NoDatabase ` - -FormatArgs @($Name,$sqlServer,$sqlInstanceName) ` - -ErrorCategory InvalidResult + -FormatArgs @($Name, $ServerName, $InstanceName) ` + -ErrorCategory InvalidResult } } - + $returnValue = @{ - Name = $Name - RecoveryModel = $sqlDatabaseRecoveryModel - SQLServer = $SQLServer - SQLInstanceName = $SQLInstanceName + Name = $Name + RecoveryModel = $sqlDatabaseRecoveryModel + ServerName = $ServerName + InstanceName = $InstanceName } $returnValue @@ -85,10 +85,10 @@ function Get-TargetResource .PARAMETER RecoveryModel This is the RecoveryModel of the SQL database - .PARAMETER SQLServer + .PARAMETER ServerName This is a the SQL Server for the database - .PARAMETER SQLInstanceName + .PARAMETER InstanceName This is a the SQL instance for the database #> function Set-TargetResource @@ -97,7 +97,7 @@ function Set-TargetResource param ( [Parameter(Mandatory = $true)] - [ValidateSet('Full','Simple','BulkLogged')] + [ValidateSet('Full', 'Simple', 'BulkLogged')] [ValidateNotNullOrEmpty()] [System.String] $RecoveryModel, @@ -105,21 +105,21 @@ function Set-TargetResource [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] - $SQLServer, + $ServerName, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] - $SQLInstanceName, + $InstanceName, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] $Name ) - - $sqlServerObject = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName - + + $sqlServerObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName + if ($sqlServerObject) { Write-Verbose -Message "Setting RecoveryModel of SQL database '$Name'" @@ -127,7 +127,7 @@ function Set-TargetResource if ($sqlDatabaseObject) { - if($sqlDatabaseObject.RecoveryModel -ne $RecoveryModel) + if ($sqlDatabaseObject.RecoveryModel -ne $RecoveryModel) { $sqlDatabaseObject.RecoveryModel = $RecoveryModel $sqlDatabaseObject.Alter() @@ -137,8 +137,8 @@ function Set-TargetResource else { throw New-TerminatingError -ErrorType NoDatabase ` - -FormatArgs @($Name,$sqlServer,$sqlInstanceName) ` - -ErrorCategory InvalidResult + -FormatArgs @($Name, $ServerName, $InstanceName) ` + -ErrorCategory InvalidResult } } } @@ -153,10 +153,10 @@ function Set-TargetResource .PARAMETER RecoveryModel This is the RecoveryModel of the SQL database - .PARAMETER SQLServer + .PARAMETER ServerName This is a the SQL Server for the database - .PARAMETER SQLInstanceName + .PARAMETER InstanceName This is a the SQL instance for the database #> function Test-TargetResource @@ -166,7 +166,7 @@ function Test-TargetResource param ( [Parameter(Mandatory = $true)] - [ValidateSet('Full','Simple','BulkLogged')] + [ValidateSet('Full', 'Simple', 'BulkLogged')] [ValidateNotNullOrEmpty()] [System.String] $RecoveryModel, @@ -174,12 +174,12 @@ function Test-TargetResource [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] - $SQLServer, + $ServerName, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] - $SQLInstanceName, + $InstanceName, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] @@ -192,8 +192,8 @@ function Test-TargetResource $currentValues = Get-TargetResource @PSBoundParameters return Test-SQLDscParameterState -CurrentValues $currentValues ` - -DesiredValues $PSBoundParameters ` - -ValuesToCheck @('Name','RecoveryModel') + -DesiredValues $PSBoundParameters ` + -ValuesToCheck @('Name', 'RecoveryModel') } Export-ModuleMember -Function *-TargetResource diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerDatabaseRecoveryModel/MSFT_xSQLServerDatabaseRecoveryModel.schema.mof b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseRecoveryModel/MSFT_SqlDatabaseRecoveryModel.schema.mof similarity index 65% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerDatabaseRecoveryModel/MSFT_xSQLServerDatabaseRecoveryModel.schema.mof rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseRecoveryModel/MSFT_SqlDatabaseRecoveryModel.schema.mof index 0ffb09a92..8e5225522 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerDatabaseRecoveryModel/MSFT_xSQLServerDatabaseRecoveryModel.schema.mof +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseRecoveryModel/MSFT_SqlDatabaseRecoveryModel.schema.mof @@ -1,8 +1,8 @@ -[ClassVersion("1.0"), FriendlyName("xSQLServerDatabaseRecoveryModel")] -class MSFT_xSQLServerDatabaseRecoveryModel : OMI_BaseResource +[ClassVersion("1.0"), FriendlyName("SqlDatabaseRecoveryModel")] +class MSFT_SqlDatabaseRecoveryModel : OMI_BaseResource { [Key, Description("The SQL database name")] String Name; [Required, Description("The recovery model to use for the database."), ValueMap{"Full","Simple","BulkLogged"}, Values{"Full","Simple","BulkLogged"}] String RecoveryModel; - [Key, Description("The host name of the SQL Server to be configured.")] String SQLServer; - [Key, Description("The name of the SQL instance to be configured.")] String SQLInstanceName; + [Key, Description("The host name of the SQL Server to be configured.")] String ServerName; + [Key, Description("The name of the SQL instance to be configured.")] String InstanceName; }; diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerDatabaseRole/MSFT_xSQLServerDatabaseRole.psm1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseRole/MSFT_SqlDatabaseRole.psm1 similarity index 71% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerDatabaseRole/MSFT_xSQLServerDatabaseRole.psm1 rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseRole/MSFT_SqlDatabaseRole.psm1 index c9c67b0bd..d762dec66 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerDatabaseRole/MSFT_xSQLServerDatabaseRole.psm1 +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseRole/MSFT_SqlDatabaseRole.psm1 @@ -1,6 +1,6 @@ Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) ` - -ChildPath 'xSQLServerHelper.psm1') ` - -Force + -ChildPath 'SqlServerDscHelper.psm1') ` + -Force <# .SYNOPSIS @@ -8,19 +8,19 @@ Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Pare .PARAMETER Ensure Specifies the desired state of the membership of the role(s). - + .PARAMETER Name Specifies the name of the login that evaluated if it is member of the role(s). - - .PARAMETER SQLServer + + .PARAMETER ServerName Specifies the SQL server on which the instance exist. - - .PARAMETER SQLInstanceName + + .PARAMETER InstanceName Specifies the SQL instance in which the database exist. - + .PARAMETER Database Specifies the database in which the login (user) and role(s) exist. - + .PARAMETER Role Specifies one or more roles to which the login (user) will be evaluated if it should be added or removed. #> @@ -38,12 +38,12 @@ function Get-TargetResource [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] - $SQLServer, + $ServerName, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] - $SQLInstanceName, + $InstanceName, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] @@ -58,7 +58,7 @@ function Get-TargetResource Write-Verbose -Message "Getting SQL Database role for $Name" - $sqlServerObject = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName + $sqlServerObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName if ($sqlServerObject) { @@ -66,18 +66,18 @@ function Get-TargetResource if ( -not ($sqlDatabaseObject = $sqlServerObject.Databases[$Database]) ) { throw New-TerminatingError -ErrorType NoDatabase ` - -FormatArgs @($Database, $SQLServer, $SQLInstanceName) ` - -ErrorCategory ObjectNotFound + -FormatArgs @($Database, $ServerName, $InstanceName) ` + -ErrorCategory ObjectNotFound } # Check role exists foreach ($currentRole in $Role) { - if( -not ($sqlDatabaseObject.Roles[$currentRole]) ) + if ( -not ($sqlDatabaseObject.Roles[$currentRole]) ) { throw New-TerminatingError -ErrorType RoleNotFound ` - -FormatArgs @($currentRole, $Database, $SQLServer, $SQLInstanceName) ` - -ErrorCategory ObjectNotFound + -FormatArgs @($currentRole, $Database, $ServerName, $InstanceName) ` + -ErrorCategory ObjectNotFound } } @@ -85,8 +85,8 @@ function Get-TargetResource if ( -not ($sqlServerObject.Logins[$Name]) ) { throw New-TerminatingError -ErrorType LoginNotFound ` - -FormatArgs @($Name, $SQLServer, $SQLInstanceName) ` - -ErrorCategory ObjectNotFound + -FormatArgs @($Name, $ServerName, $InstanceName) ` + -ErrorCategory ObjectNotFound } $ensure = 'Absent' @@ -99,14 +99,14 @@ function Get-TargetResource if ($sqlDatabaseUser.IsMember($currentRole)) { New-VerboseMessage -Message ("The login '$Name' is a member of the role '$currentRole' on the " + ` - "database '$Database', on the instance $SQLServer\$SQLInstanceName") - + "database '$Database', on the instance $ServerName\$InstanceName") + $grantedRole += $currentRole } else { New-VerboseMessage -Message ("The login '$Name' is not a member of the role '$currentRole' on the " + ` - "database '$Database', on the instance $SQLServer\$SQLInstanceName") + "database '$Database', on the instance $ServerName\$InstanceName") } } @@ -118,17 +118,17 @@ function Get-TargetResource else { New-VerboseMessage -Message ("The login '$Name' is not a user of the database " + ` - "'$Database' on the instance $SQLServer\$SQLInstanceName") + "'$Database' on the instance $ServerName\$InstanceName") } } $returnValue = @{ - Ensure = $ensure - Name = $Name - SQLServer = $SQLServer - SQLInstanceName = $SQLInstanceName - Database = $Database - Role = $grantedRole + Ensure = $ensure + Name = $Name + ServerName = $ServerName + InstanceName = $InstanceName + Database = $Database + Role = $grantedRole } $returnValue @@ -142,20 +142,20 @@ function Get-TargetResource .PARAMETER Ensure Specifies the desired state of the membership of the role(s). - + .PARAMETER Name Specifies the name of the login that evaluated if it is member of the role(s), if it is not it will be added. - If the login does not exist as a user, a user will be created using the login. - - .PARAMETER SQLServer + If the login does not exist as a user, a user will be created using the login. + + .PARAMETER ServerName Specifies the SQL server on which the instance exist. - - .PARAMETER SQLInstanceName + + .PARAMETER InstanceName Specifies the SQL instance in which the database exist. - + .PARAMETER Database Specifies the database in which the login (user) and role(s) exist. - + .PARAMETER Role Specifies one or more roles to which the login (user) will be added or removed. #> @@ -165,7 +165,7 @@ function Set-TargetResource param ( [Parameter()] - [ValidateSet('Present','Absent')] + [ValidateSet('Present', 'Absent')] [ValidateNotNullOrEmpty()] [System.String] $Ensure = 'Present', @@ -178,12 +178,12 @@ function Set-TargetResource [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] - $SQLServer, + $ServerName, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] - $SQLInstanceName, + $InstanceName, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] @@ -198,12 +198,12 @@ function Set-TargetResource Write-Verbose -Message "Setting SQL Database role for $Name" - $sqlServerObject = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName + $sqlServerObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName if ($sqlServerObject) { $sqlDatabaseObject = $sqlServerObject.Databases[$Database] - + switch ($Ensure) { 'Present' @@ -214,29 +214,29 @@ function Set-TargetResource try { New-VerboseMessage -Message ("Adding the login '$Name' as a user of the database " + ` - "'$Database', on the instance $SQLServer\$SQLInstanceName") + "'$Database', on the instance $ServerName\$InstanceName") $sqlDatabaseUser = New-Object -TypeName Microsoft.SqlServer.Management.Smo.User ` - -ArgumentList $SQLDatabase, $Name + -ArgumentList $sqlDatabaseObject, $Name $sqlDatabaseUser.Login = $Name $sqlDatabaseUser.Create() } catch { throw New-TerminatingError -ErrorType AddLoginDatabaseSetError ` - -FormatArgs @($SQLServer,$SQLInstanceName,$Name,$Database) ` - -ErrorCategory InvalidOperation ` - -InnerException $_.Exception + -FormatArgs @($ServerName, $InstanceName, $Name, $Database) ` + -ErrorCategory InvalidOperation ` + -InnerException $_.Exception } } # Adding database user to the role. - foreach ($currentRole in $Role) + foreach ($currentRole in $Role) { try { New-VerboseMessage -Message ("Adding the login '$Name' to the role '$currentRole' on the " + ` - "database '$Database', on the instance $SQLServer\$SQLInstanceName") + "database '$Database', on the instance $ServerName\$InstanceName") $sqlDatabaseRole = $sqlDatabaseObject.Roles[$currentRole] $sqlDatabaseRole.AddMember($Name) @@ -244,9 +244,9 @@ function Set-TargetResource catch { throw New-TerminatingError -ErrorType AddMemberDatabaseSetError ` - -FormatArgs @($SQLServer,$SQLInstanceName,$Name,$Role,$Database) ` - -ErrorCategory InvalidOperation ` - -InnerException $_.Exception + -FormatArgs @($ServerName, $InstanceName, $Name, $Role, $Database) ` + -ErrorCategory InvalidOperation ` + -InnerException $_.Exception } } } @@ -255,10 +255,10 @@ function Set-TargetResource { try { - foreach ($currentRole in $Role) + foreach ($currentRole in $Role) { New-VerboseMessage -Message ("Removing the login '$Name' to the role '$currentRole' on the " + ` - "database '$Database', on the instance $SQLServer\$SQLInstanceName") + "database '$Database', on the instance $ServerName\$InstanceName") $sqlDatabaseRole = $sqlDatabaseObject.Roles[$currentRole] $sqlDatabaseRole.DropMember($Name) @@ -267,9 +267,9 @@ function Set-TargetResource catch { throw New-TerminatingError -ErrorType DropMemberDatabaseSetError ` - -FormatArgs @($SQLServer,$SQLInstanceName,$Name,$Role,$Database) ` - -ErrorCategory InvalidOperation ` - -InnerException $_.Exception + -FormatArgs @($ServerName, $InstanceName, $Name, $Role, $Database) ` + -ErrorCategory InvalidOperation ` + -InnerException $_.Exception } } } @@ -282,19 +282,19 @@ function Set-TargetResource .PARAMETER Ensure Specifies the desired state of the membership of the role(s). - + .PARAMETER Name Specifies the name of the login that evaluated if it is member of the role(s). - - .PARAMETER SQLServer + + .PARAMETER ServerName Specifies the SQL server on which the instance exist. - - .PARAMETER SQLInstanceName + + .PARAMETER InstanceName Specifies the SQL instance in which the database exist. - + .PARAMETER Database Specifies the database in which the login (user) and role(s) exist. - + .PARAMETER Role Specifies one or more roles to which the login (user) will be tested if it should added or removed. #> @@ -305,7 +305,7 @@ function Test-TargetResource param ( [Parameter()] - [ValidateSet('Present','Absent')] + [ValidateSet('Present', 'Absent')] [ValidateNotNullOrEmpty()] [System.String] $Ensure = 'Present', @@ -318,12 +318,12 @@ function Test-TargetResource [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] - $SQLServer, + $ServerName, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] - $SQLInstanceName, + $InstanceName, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] @@ -337,19 +337,19 @@ function Test-TargetResource ) Write-Verbose -Message "Testing SQL Database role for $Name" - + $getTargetResourceParameters = @{ - SQLInstanceName = $PSBoundParameters.SQLInstanceName - SQLServer = $PSBoundParameters.SQLServer - Role = $PSBoundParameters.Role - Database = $PSBoundParameters.Database - Name = $PSBoundParameters.Name + InstanceName = $PSBoundParameters.InstanceName + ServerName = $PSBoundParameters.ServerName + Role = $PSBoundParameters.Role + Database = $PSBoundParameters.Database + Name = $PSBoundParameters.Name } $getTargetResourceResult = Get-TargetResource @getTargetResourceParameters - + $isDatabaseRoleInDesiredState = $true - + switch ($Ensure) { 'Absent' @@ -360,7 +360,7 @@ function Test-TargetResource $isDatabaseRoleInDesiredState = $false } } - + 'Present' { if ($getTargetResourceResult.Ensure -ne 'Present') @@ -371,7 +371,7 @@ function Test-TargetResource } } - $isDatabaseRoleInDesiredState + $isDatabaseRoleInDesiredState } Export-ModuleMember -Function *-TargetResource diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerDatabaseRole/MSFT_xSQLServerDatabaseRole.schema.mof b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseRole/MSFT_SqlDatabaseRole.schema.mof similarity index 80% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerDatabaseRole/MSFT_xSQLServerDatabaseRole.schema.mof rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseRole/MSFT_SqlDatabaseRole.schema.mof index ef07952f9..85d405360 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerDatabaseRole/MSFT_xSQLServerDatabaseRole.schema.mof +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlDatabaseRole/MSFT_SqlDatabaseRole.schema.mof @@ -1,10 +1,10 @@ -[ClassVersion("1.0.0.0"), FriendlyName("xSQLServerDatabaseRole")] -class MSFT_xSQLServerDatabaseRole : OMI_BaseResource +[ClassVersion("1.0.0.0"), FriendlyName("SqlDatabaseRole")] +class MSFT_SqlDatabaseRole : OMI_BaseResource { [Write, Description("If 'Present' (the default value) then the login (user) will be added to the role(s). If 'Absent' then the login (user) will be removed from the role(s)."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; [Key, Description("The name of the login that will become a member, or removed as a member, of the role(s).")] String Name; - [Key, Description("The host name of the SQL Server to be configured.")] String SQLServer; - [Key, Description("The name of the SQL instance to be configured.")] String SQLInstanceName; + [Key, Description("The host name of the SQL Server to be configured.")] String ServerName; + [Key, Description("The name of the SQL instance to be configured.")] String InstanceName; [Key, Description("The database in which the login (user) and role(s) exist.")] String Database; [Required, Description("One or more roles to which the login (user) will be added or removed.")] String Role[]; }; diff --git a/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlRS/MSFT_SqlRS.psm1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlRS/MSFT_SqlRS.psm1 new file mode 100644 index 000000000..9391a41c5 --- /dev/null +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlRS/MSFT_SqlRS.psm1 @@ -0,0 +1,926 @@ +Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) ` + -ChildPath 'SqlServerDscHelper.psm1') ` + -Force + +<# + .SYNOPSIS + Gets the SQL Reporting Services initialization status. + + .PARAMETER InstanceName + Name of the SQL Server Reporting Services instance to be configured. + + .PARAMETER DatabaseServerName + Name of the SQL Server to host the Reporting Service database. + + .PARAMETER DatabaseInstanceName + Name of the SQL Server instance to host the Reporting Service database. +#> +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $InstanceName, + + [Parameter(Mandatory = $true)] + [System.String] + $DatabaseServerName, + + [Parameter(Mandatory = $true)] + [System.String] + $DatabaseInstanceName + ) + + $reportingServicesData = Get-ReportingServicesData -InstanceName $InstanceName + + if ( $null -ne $reportingServicesData.Configuration ) + { + if ( $reportingServicesData.Configuration.DatabaseServerName.Contains('\') ) + { + $DatabaseServerName = $reportingServicesData.Configuration.DatabaseServerName.Split('\')[0] + $DatabaseInstanceName = $reportingServicesData.Configuration.DatabaseServerName.Split('\')[1] + } + else + { + $DatabaseServerName = $reportingServicesData.Configuration.DatabaseServerName + $DatabaseInstanceName = 'MSSQLSERVER' + } + + $isInitialized = $reportingServicesData.Configuration.IsInitialized + + if ( $isInitialized ) + { + if ( $reportingServicesData.Configuration.SecureConnectionLevel ) + { + $isUsingSsl = $true + } + else + { + $isUsingSsl = $false + } + + $reportServerVirtualDirectory = $reportingServicesData.Configuration.VirtualDirectoryReportServer + $reportsVirtualDirectory = $reportingServicesData.Configuration.VirtualDirectoryReportManager + + $invokeRsCimMethodParameters = @{ + CimInstance = $reportingServicesData.Configuration + MethodName = 'ListReservedUrls' + } + + $reservedUrls = Invoke-RsCimMethod @invokeRsCimMethodParameters + + $reportServerReservedUrl = @() + $reportsReservedUrl = @() + + for ( $i = 0; $i -lt $reservedUrls.Application.Count; ++$i ) + { + if ( $reservedUrls.Application[$i] -eq 'ReportServerWebService' ) + { + $reportServerReservedUrl += $reservedUrls.UrlString[$i] + } + + if ( $reservedUrls.Application[$i] -eq $reportingServicesData.ReportsApplicationName ) + { + $reportsReservedUrl += $reservedUrls.UrlString[$i] + } + } + } + else + { + <# + Make sure the value returned is false, if the value returned was + either empty, $null or $false. Fic for issue #822. + #> + [System.Boolean] $isInitialized = $false + } + } + else + { + throw New-TerminatingError -ErrorType SSRSNotFound -FormatArgs @($InstanceName) -ErrorCategory ObjectNotFound + } + + return @{ + InstanceName = $InstanceName + DatabaseServerName = $DatabaseServerName + DatabaseInstanceName = $DatabaseInstanceName + ReportServerVirtualDirectory = $reportServerVirtualDirectory + ReportsVirtualDirectory = $reportsVirtualDirectory + ReportServerReservedUrl = $reportServerReservedUrl + ReportsReservedUrl = $reportsReservedUrl + UseSsl = $isUsingSsl + IsInitialized = $isInitialized + } +} + +<# + .SYNOPSIS + Initializes SQL Reporting Services. + + .PARAMETER InstanceName + Name of the SQL Server Reporting Services instance to be configured. + + .PARAMETER DatabaseServerName + Name of the SQL Server to host the Reporting Service database. + + .PARAMETER DatabaseInstanceName + Name of the SQL Server instance to host the Reporting Service database. + + .PARAMETER ReportServerVirtualDirectory + Report Server Web Service virtual directory. Optional. + + .PARAMETER ReportsVirtualDirectory + Report Manager/Report Web App virtual directory name. Optional. + + .PARAMETER ReportServerReservedUrl + Report Server URL reservations. Optional. If not specified, + 'http://+:80' URL reservation will be used. + + .PARAMETER ReportsReservedUrl + Report Manager/Report Web App URL reservations. Optional. + If not specified, 'http://+:80' URL reservation will be used. + + .PARAMETER UseSsl + If connections to the Reporting Services must use SSL. If this + parameter is not assigned a value, the default is that Reporting + Services does not use SSL. + + .NOTES + To find out the parameter names for the methods in the class + MSReportServer_ConfigurationSetting it's easy to list them using the + following code. Example for listing + + ``` + $methodName = 'ReserveUrl' + $instanceName = 'SQL2016' + $sqlMajorVersion = '13' + $getCimClassParameters = @{ + ClassName = 'MSReportServer_ConfigurationSetting' + Namespace = "root\Microsoft\SQLServer\ReportServer\RS_$instanceName\v$sqlMajorVersion\Admin" + } + (Get-CimClass @getCimClassParameters).CimClassMethods[$methodName].Parameters + ``` + + Or run the following using the helper function in this code. Make sure + to have the helper function loaded in the session. + + ``` + $methodName = 'ReserveUrl' + $instanceName = 'SQL2016' + $reportingServicesData = Get-ReportingServicesData -InstanceName $InstanceName + $reportingServicesData.Configuration.CimClass.CimClassMethods[$methodName].Parameters + ``` + + SecureConnectionLevel (the parameter UseSsl): + The SecureConnectionLevel value can be 0,1,2 or 3, but since + SQL Server 2008 R2 this was changed. So we are just setting it to 0 (off) + and 1 (on). + + "In SQL Server 2008 R2, SecureConnectionLevel is made an on/off + switch, default value is 0. For any value greater than or equal + to 1 passed through SetSecureConnectionLevel method API, SSL + is considered on..." + https://docs.microsoft.com/en-us/sql/reporting-services/wmi-provider-library-reference/configurationsetting-method-setsecureconnectionlevel +#> +function Set-TargetResource +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $InstanceName, + + [Parameter(Mandatory = $true)] + [System.String] + $DatabaseServerName, + + [Parameter(Mandatory = $true)] + [System.String] + $DatabaseInstanceName, + + [Parameter()] + [System.String] + $ReportServerVirtualDirectory, + + [Parameter()] + [System.String] + $ReportsVirtualDirectory, + + [Parameter()] + [System.String[]] + $ReportServerReservedUrl, + + [Parameter()] + [System.String[]] + $ReportsReservedUrl, + + [Parameter()] + [System.Boolean] + $UseSsl + ) + + $reportingServicesData = Get-ReportingServicesData -InstanceName $InstanceName + + if ( $null -ne $reportingServicesData.Configuration ) + { + if ( $InstanceName -eq 'MSSQLSERVER' ) + { + if ( [System.String]::IsNullOrEmpty($ReportServerVirtualDirectory) ) + { + $ReportServerVirtualDirectory = 'ReportServer' + } + + if ( [System.String]::IsNullOrEmpty($ReportsVirtualDirectory) ) + { + $ReportsVirtualDirectory = 'Reports' + } + + $reportingServicesServiceName = 'ReportServer' + $reportingServicesDatabaseName = 'ReportServer' + } + else + { + if ( [System.String]::IsNullOrEmpty($ReportServerVirtualDirectory) ) + { + $ReportServerVirtualDirectory = "ReportServer_$InstanceName" + } + + if ( [System.String]::IsNullOrEmpty($ReportsVirtualDirectory) ) + { + $ReportsVirtualDirectory = "Reports_$InstanceName" + } + + $reportingServicesServiceName = "ReportServer`$$InstanceName" + $reportingServicesDatabaseName = "ReportServer`$$InstanceName" + } + + if ( $DatabaseInstanceName -eq 'MSSQLSERVER' ) + { + $reportingServicesConnection = $DatabaseServerName + } + else + { + $reportingServicesConnection = "$DatabaseServerName\$DatabaseInstanceName" + } + + $wmiOperatingSystem = Get-CimInstance -ClassName Win32_OperatingSystem -Namespace 'root/cimv2' -ErrorAction SilentlyContinue + if ( $null -eq $wmiOperatingSystem ) + { + throw 'Unable to find WMI object Win32_OperatingSystem.' + } + + $language = $wmiOperatingSystem.OSLanguage + + if ( -not $reportingServicesData.Configuration.IsInitialized ) + { + New-VerboseMessage -Message "Initializing Reporting Services on $DatabaseServerName\$DatabaseInstanceName." + + # If no Report Server reserved URLs have been specified, use the default one. + if ( $null -eq $ReportServerReservedUrl ) + { + $ReportServerReservedUrl = @('http://+:80') + } + + # If no Report Manager/Report Web App reserved URLs have been specified, use the default one. + if ( $null -eq $ReportsReservedUrl ) + { + $ReportsReservedUrl = @('http://+:80') + } + + if ( $reportingServicesData.Configuration.VirtualDirectoryReportServer -ne $ReportServerVirtualDirectory ) + { + New-VerboseMessage -Message "Setting report server virtual directory on $DatabaseServerName\$DatabaseInstanceName to $ReportServerVirtualDirectory." + + $invokeRsCimMethodParameters = @{ + CimInstance = $reportingServicesData.Configuration + MethodName = 'SetVirtualDirectory' + Arguments = @{ + Application = 'ReportServerWebService' + VirtualDirectory = $ReportServerVirtualDirectory + Lcid = $language + } + } + + Invoke-RsCimMethod @invokeRsCimMethodParameters + + $ReportServerReservedUrl | ForEach-Object -Process { + New-VerboseMessage -Message "Adding report server URL reservation on $DatabaseServerName\$DatabaseInstanceName`: $_." + + $invokeRsCimMethodParameters = @{ + CimInstance = $reportingServicesData.Configuration + MethodName = 'ReserveUrl' + Arguments = @{ + Application = 'ReportServerWebService' + UrlString = $_ + Lcid = $language + } + } + + Invoke-RsCimMethod @invokeRsCimMethodParameters + } + } + + if ( $reportingServicesData.Configuration.VirtualDirectoryReportManager -ne $ReportsVirtualDirectory ) + { + New-VerboseMessage -Message "Setting reports virtual directory on $DatabaseServerName\$DatabaseInstanceName to $ReportServerVirtualDirectory." + + $invokeRsCimMethodParameters = @{ + CimInstance = $reportingServicesData.Configuration + MethodName = 'SetVirtualDirectory' + Arguments = @{ + Application = $reportingServicesData.ReportsApplicationName + VirtualDirectory = $ReportsVirtualDirectory + Lcid = $language + } + } + + Invoke-RsCimMethod @invokeRsCimMethodParameters + + $ReportsReservedUrl | ForEach-Object -Process { + New-VerboseMessage -Message "Adding reports URL reservation on $DatabaseServerName\$DatabaseInstanceName`: $_." + + $invokeRsCimMethodParameters = @{ + CimInstance = $reportingServicesData.Configuration + MethodName = 'ReserveUrl' + Arguments = @{ + Application = $reportingServicesData.ReportsApplicationName + UrlString = $_ + Lcid = $language + } + } + + Invoke-RsCimMethod @invokeRsCimMethodParameters + } + } + + $invokeRsCimMethodParameters = @{ + CimInstance = $reportingServicesData.Configuration + MethodName = 'GenerateDatabaseCreationScript' + Arguments = @{ + DatabaseName = $reportingServicesDatabaseName + IsSharePointMode = $false + Lcid = $language + } + } + + $reportingServicesDatabaseScript = Invoke-RsCimMethod @invokeRsCimMethodParameters + + # Determine RS service account + $reportingServicesServiceAccountUserName = (Get-CimInstance -ClassName Win32_Service | Where-Object -FilterScript { + $_.Name -eq $reportingServicesServiceName + }).StartName + + $invokeRsCimMethodParameters = @{ + CimInstance = $reportingServicesData.Configuration + MethodName = 'GenerateDatabaseRightsScript' + Arguments = @{ + DatabaseName = $reportingServicesDatabaseName + UserName = $reportingServicesServiceAccountUserName + IsRemote = $false + IsWindowsUser = $true + } + } + + $reportingServicesDatabaseRightsScript = Invoke-RsCimMethod @invokeRsCimMethodParameters + + <# + Import-SQLPSModule cmdlet will import SQLPS (SQL 2012/14) or SqlServer module (SQL 2016), + and if importing SQLPS, change directory back to the original one, since SQLPS changes the + current directory to SQLSERVER:\ on import. + #> + Import-SQLPSModule + Invoke-Sqlcmd -ServerInstance $reportingServicesConnection -Query $reportingServicesDatabaseScript.Script + Invoke-Sqlcmd -ServerInstance $reportingServicesConnection -Query $reportingServicesDatabaseRightsScript.Script + + $invokeRsCimMethodParameters = @{ + CimInstance = $reportingServicesData.Configuration + MethodName = 'SetDatabaseConnection' + Arguments = @{ + Server = $reportingServicesConnection + DatabaseName = $reportingServicesDatabaseName + Username = '' + Password = '' + + <# + Can be set to either: + 0 = Windows + 1 = Sql Server + 2 = Windows Service (Integrated Security) + + When set to 2 the Reporting Server Web service will use + either the ASP.NET account or an application pool’s account + and the Windows service account to access the report server + database. + + See more in the article + https://docs.microsoft.com/en-us/sql/reporting-services/wmi-provider-library-reference/configurationsetting-method-setdatabaseconnection#remarks + + #> + CredentialsType = 2 + } + } + + Invoke-RsCimMethod @invokeRsCimMethodParameters + + $invokeRsCimMethodParameters = @{ + CimInstance = $reportingServicesData.Configuration + MethodName = 'InitializeReportServer' + Arguments = @{ + InstallationId = $reportingServicesData.Configuration.InstallationID + } + } + + Invoke-RsCimMethod @invokeRsCimMethodParameters + + if ( $PSBoundParameters.ContainsKey('UseSsl') -and $UseSsl -ne $currentConfig.UseSsl ) + { + New-VerboseMessage -Message "Changing value for using SSL to '$UseSsl'." + + $invokeRsCimMethodParameters = @{ + CimInstance = $reportingServicesData.Configuration + MethodName = 'SetSecureConnectionLevel' + Arguments = @{ + Level = @(0,1)[$UseSsl] + } + } + + Invoke-RsCimMethod @invokeRsCimMethodParameters + } + + Restart-ReportingServicesService -SQLInstanceName $InstanceName + } + else + { + $getTargetResourceParameters = @{ + InstanceName = $InstanceName + DatabaseServerName = $DatabaseServerName + DatabaseInstanceName = $DatabaseInstanceName + } + + $currentConfig = Get-TargetResource @getTargetResourceParameters + + <# + SQL Server Reporting Services virtual directories (both + Report Server and Report Manager/Report Web App) are a + part of SQL Server Reporting Services URL reservations. + + The default SQL Server Reporting Services URL reservations are: + http://+:80/ReportServer/ (for Report Server) + and + http://+:80/Reports/ (for Report Manager/Report Web App) + + You can get them by running 'netsh http show urlacl' from + command line. + + In order to change a virtual directory, we first need to remove + existing URL reservations, change the appropriate virtual directory + setting and re-add URL reservations, which will then contain the + new virtual directory. + #> + + if ( -not [System.String]::IsNullOrEmpty($ReportServerVirtualDirectory) -and ($ReportServerVirtualDirectory -ne $currentConfig.ReportServerVirtualDirectory) ) + { + New-VerboseMessage -Message "Setting report server virtual directory on $DatabaseServerName\$DatabaseInstanceName to $ReportServerVirtualDirectory." + + $currentConfig.ReportServerReservedUrl | ForEach-Object -Process { + $invokeRsCimMethodParameters = @{ + CimInstance = $reportingServicesData.Configuration + MethodName = 'RemoveURL' + Arguments = @{ + Application = 'ReportServerWebService' + UrlString = $_ + Lcid = $language + } + } + + Invoke-RsCimMethod @invokeRsCimMethodParameters + } + + $invokeRsCimMethodParameters = @{ + CimInstance = $reportingServicesData.Configuration + MethodName = 'SetVirtualDirectory' + Arguments = @{ + Application = 'ReportServerWebService' + VirtualDirectory = $ReportServerVirtualDirectory + Lcid = $language + } + } + + Invoke-RsCimMethod @invokeRsCimMethodParameters + + $currentConfig.ReportServerReservedUrl | ForEach-Object -Process { + $invokeRsCimMethodParameters = @{ + CimInstance = $reportingServicesData.Configuration + MethodName = 'ReserveUrl' + Arguments = @{ + Application = 'ReportServerWebService' + UrlString = $_ + Lcid = $language + } + } + + Invoke-RsCimMethod @invokeRsCimMethodParameters + } + } + + if ( -not [System.String]::IsNullOrEmpty($ReportsVirtualDirectory) -and ($ReportsVirtualDirectory -ne $currentConfig.ReportsVirtualDirectory) ) + { + New-VerboseMessage -Message "Setting reports virtual directory on $DatabaseServerName\$DatabaseInstanceName to $ReportServerVirtualDirectory." + + $currentConfig.ReportsReservedUrl | ForEach-Object -Process { + $invokeRsCimMethodParameters = @{ + CimInstance = $reportingServicesData.Configuration + MethodName = 'RemoveURL' + Arguments = @{ + Application = $reportingServicesData.ReportsApplicationName + UrlString = $_ + Lcid = $language + } + } + + Invoke-RsCimMethod @invokeRsCimMethodParameters + } + + $invokeRsCimMethodParameters = @{ + CimInstance = $reportingServicesData.Configuration + MethodName = 'SetVirtualDirectory' + Arguments = @{ + Application = $reportingServicesData.ReportsApplicationName + VirtualDirectory = $ReportsVirtualDirectory + Lcid = $language + } + } + + Invoke-RsCimMethod @invokeRsCimMethodParameters + + $currentConfig.ReportsReservedUrl | ForEach-Object -Process { + $invokeRsCimMethodParameters = @{ + CimInstance = $reportingServicesData.Configuration + MethodName = 'ReserveUrl' + Arguments = @{ + Application = $reportingServicesData.ReportsApplicationName + UrlString = $_ + Lcid = $language + } + } + + Invoke-RsCimMethod @invokeRsCimMethodParameters + } + } + + $compareParameters = @{ + ReferenceObject = $currentConfig.ReportServerReservedUrl + DifferenceObject = $ReportServerReservedUrl + } + + if ( ($null -ne $ReportServerReservedUrl) -and ($null -ne (Compare-Object @compareParameters)) ) + { + $currentConfig.ReportServerReservedUrl | ForEach-Object -Process { + $invokeRsCimMethodParameters = @{ + CimInstance = $reportingServicesData.Configuration + MethodName = 'RemoveURL' + Arguments = @{ + Application = 'ReportServerWebService' + UrlString = $_ + Lcid = $language + } + } + + Invoke-RsCimMethod @invokeRsCimMethodParameters + } + + $ReportServerReservedUrl | ForEach-Object -Process { + New-VerboseMessage -Message "Adding report server URL reservation on $DatabaseServerName\$DatabaseInstanceName`: $_." + $invokeRsCimMethodParameters = @{ + CimInstance = $reportingServicesData.Configuration + MethodName = 'ReserveUrl' + Arguments = @{ + Application = 'ReportServerWebService' + UrlString = $_ + Lcid = $language + } + } + + Invoke-RsCimMethod @invokeRsCimMethodParameters + } + } + + $compareParameters = @{ + ReferenceObject = $currentConfig.ReportsReservedUrl + DifferenceObject = $ReportsReservedUrl + } + + if ( ($null -ne $ReportsReservedUrl) -and ($null -ne (Compare-Object @compareParameters)) ) + { + $currentConfig.ReportsReservedUrl | ForEach-Object -Process { + $invokeRsCimMethodParameters = @{ + CimInstance = $reportingServicesData.Configuration + MethodName = 'RemoveURL' + Arguments = @{ + Application = $reportingServicesData.ReportsApplicationName + UrlString = $_ + Lcid = $language + } + } + + Invoke-RsCimMethod @invokeRsCimMethodParameters + } + + $ReportsReservedUrl | ForEach-Object -Process { + New-VerboseMessage -Message "Adding reports URL reservation on $DatabaseServerName\$DatabaseInstanceName`: $_." + + $invokeRsCimMethodParameters = @{ + CimInstance = $reportingServicesData.Configuration + MethodName = 'ReserveUrl' + Arguments = @{ + Application = $reportingServicesData.ReportsApplicationName + UrlString = $_ + Lcid = $language + } + } + + Invoke-RsCimMethod @invokeRsCimMethodParameters + } + } + + if ( $PSBoundParameters.ContainsKey('UseSsl') -and $UseSsl -ne $currentConfig.UseSsl ) + { + New-VerboseMessage -Message "Changing value for using SSL to '$UseSsl'." + + $invokeRsCimMethodParameters = @{ + CimInstance = $reportingServicesData.Configuration + MethodName = 'SetSecureConnectionLevel' + Arguments = @{ + Level = @(0,1)[$UseSsl] + } + } + + Invoke-RsCimMethod @invokeRsCimMethodParameters + } + } + } + + if ( -not (Test-TargetResource @PSBoundParameters) ) + { + throw New-TerminatingError -ErrorType TestFailedAfterSet -ErrorCategory InvalidResult + } +} + +<# + .SYNOPSIS + Tests the SQL Reporting Services initialization status. + + .PARAMETER InstanceName + Name of the SQL Server Reporting Services instance to be configured. + + .PARAMETER DatabaseServerName + Name of the SQL Server to host the Reporting Service database. + + .PARAMETER DatabaseInstanceName + Name of the SQL Server instance to host the Reporting Service database. + + .PARAMETER ReportServerVirtualDirectory + Report Server Web Service virtual directory. Optional. + + .PARAMETER ReportsVirtualDirectory + Report Manager/Report Web App virtual directory name. Optional. + + .PARAMETER ReportServerReservedUrl + Report Server URL reservations. Optional. If not specified, + http://+:80' URL reservation will be used. + + .PARAMETER ReportsReservedUrl + Report Manager/Report Web App URL reservations. Optional. + If not specified, 'http://+:80' URL reservation will be used. + + .PARAMETER UseSsl + If connections to the Reporting Services must use SSL. If this + parameter is not assigned a value, the default is that Reporting + Services does not use SSL. +#> +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $InstanceName, + + [Parameter(Mandatory = $true)] + [System.String] + $DatabaseServerName, + + [Parameter(Mandatory = $true)] + [System.String] + $DatabaseInstanceName, + + [Parameter()] + [System.String] + $ReportServerVirtualDirectory, + + [Parameter()] + [System.String] + $ReportsVirtualDirectory, + + [Parameter()] + [System.String[]] + $ReportServerReservedUrl, + + [Parameter()] + [System.String[]] + $ReportsReservedUrl, + + [Parameter()] + [System.Boolean] + $UseSsl + ) + + $result = $true + + $getTargetResourceParameters = @{ + InstanceName = $InstanceName + DatabaseServerName = $DatabaseServerName + DatabaseInstanceName = $DatabaseInstanceName + } + + $currentConfig = Get-TargetResource @getTargetResourceParameters + + if ( -not $currentConfig.IsInitialized ) + { + New-VerboseMessage -Message "Reporting services $DatabaseServerName\$DatabaseInstanceName are not initialized." + $result = $false + } + + if ( -not [System.String]::IsNullOrEmpty($ReportServerVirtualDirectory) -and ($ReportServerVirtualDirectory -ne $currentConfig.ReportServerVirtualDirectory) ) + { + New-VerboseMessage -Message "Report server virtual directory on $DatabaseServerName\$DatabaseInstanceName is $($currentConfig.ReportServerVirtualDir), should be $ReportServerVirtualDirectory." + $result = $false + } + + if ( -not [System.String]::IsNullOrEmpty($ReportsVirtualDirectory) -and ($ReportsVirtualDirectory -ne $currentConfig.ReportsVirtualDirectory) ) + { + New-VerboseMessage -Message "Reports virtual directory on $DatabaseServerName\$DatabaseInstanceName is $($currentConfig.ReportsVirtualDir), should be $ReportsVirtualDirectory." + $result = $false + } + + $compareParameters = @{ + ReferenceObject = $currentConfig.ReportServerReservedUrl + DifferenceObject = $ReportServerReservedUrl + } + + if ( ($null -ne $ReportServerReservedUrl) -and ($null -ne (Compare-Object @compareParameters)) ) + { + New-VerboseMessage -Message "Report server reserved URLs on $DatabaseServerName\$DatabaseInstanceName are $($currentConfig.ReportServerReservedUrl -join ', '), should be $($ReportServerReservedUrl -join ', ')." + $result = $false + } + + $compareParameters = @{ + ReferenceObject = $currentConfig.ReportsReservedUrl + DifferenceObject = $ReportsReservedUrl + } + + if ( ($null -ne $ReportsReservedUrl) -and ($null -ne (Compare-Object @compareParameters)) ) + { + New-VerboseMessage -Message "Reports reserved URLs on $DatabaseServerName\$DatabaseInstanceName are $($currentConfig.ReportsReservedUrl -join ', ')), should be $($ReportsReservedUrl -join ', ')." + $result = $false + } + + if ( $PSBoundParameters.ContainsKey('UseSsl') -and $UseSsl -ne $currentConfig.UseSsl ) + { + New-VerboseMessage -Message "The value for using SSL are not in desired state. Should be '$UseSsl', but was '$($currentConfig.UseSsl)'." + $result = $false + } + + $result +} + +<# + .SYNOPSIS + Returns SQL Reporting Services data: configuration object used to initialize and configure + SQL Reporting Services and the name of the Reports Web application name (changed in SQL 2016) + + .PARAMETER InstanceName + Name of the SQL Server Reporting Services instance for which the data is being retrieved. +#> +function Get-ReportingServicesData +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $InstanceName + ) + + $instanceNamesRegistryKey = 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\RS' + + if ( Get-ItemProperty -Path $instanceNamesRegistryKey -Name $InstanceName -ErrorAction SilentlyContinue ) + { + $instanceId = (Get-ItemProperty -Path $instanceNamesRegistryKey -Name $InstanceName).$InstanceName + $sqlVersion = [System.Int32]((Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$instanceId\Setup" -Name 'Version').Version).Split('.')[0] + $reportingServicesConfiguration = Get-CimInstance -ClassName MSReportServer_ConfigurationSetting -Namespace "root\Microsoft\SQLServer\ReportServer\RS_$InstanceName\v$sqlVersion\Admin" + $reportingServicesConfiguration = $reportingServicesConfiguration | Where-Object -FilterScript { + $_.InstanceName -eq $InstanceName + } + <# + SQL Server Reporting Services Web Portal application name changed + in SQL Server 2016. + https://docs.microsoft.com/en-us/sql/reporting-services/breaking-changes-in-sql-server-reporting-services-in-sql-server-2016 + #> + if ( $sqlVersion -ge 13 ) + { + $reportsApplicationName = 'ReportServerWebApp' + } + else + { + $reportsApplicationName = 'ReportManager' + } + } + + @{ + Configuration = $reportingServicesConfiguration + ReportsApplicationName = $reportsApplicationName + } +} + +<# + .SYNOPSIS + A wrapper for Invoke-CimMethod to be able to handle errors in one place. + + .PARAMETER CimInstance + The CIM instance object that contains the method to call. + + .PARAMETER MethodName + The method to call in the CIM Instance object. + + .PARAMETER Arguments + The arguments that should be +#> +function Invoke-RsCimMethod +{ + [CmdletBinding()] + [OutputType([Microsoft.Management.Infrastructure.CimMethodResult])] + param + ( + + [Parameter(Mandatory = $true)] + [Microsoft.Management.Infrastructure.CimInstance] + $CimInstance, + + [Parameter(Mandatory = $true)] + [System.String] + $MethodName, + + [Parameter()] + [System.Collections.Hashtable] + $Arguments + ) + + $invokeCimMethodParameters = @{ + MethodName = $MethodName + ErrorAction = 'Stop' + } + + if ($PSBoundParameters.ContainsKey('Arguments')) + { + $invokeCimMethodParameters['Arguments'] = $Arguments + } + + $invokeCimMethodResult = $CimInstance | Invoke-CimMethod @invokeCimMethodParameters + <# + Successfully calling the method returns $invokeCimMethodResult.HRESULT -eq 0. + If an general error occur in the Invoke-CimMethod, like calling a method + that does not exist, returns $null in $invokeCimMethodResult. + #> + if ($invokeCimMethodResult -and $invokeCimMethodResult.HRESULT -ne 0) + { + if ($invokeCimMethodResult | Get-Member -Name 'ExtendedErrors') + { + <# + The returned object property ExtendedErrors is an array + so that needs to be concatenated. + #> + $errorMessage = $invokeCimMethodResult.ExtendedErrors -join ';' + } + else + { + $errorMessage = $invokeCimMethodResult.Error + } + + throw 'Method {0}() failed with an error. Error: {1} (HRESULT:{2})' -f @( + $MethodName + $errorMessage + $invokeCimMethodResult.HRESULT + ) + } + + return $invokeCimMethodResult +} + +Export-ModuleMember -Function *-TargetResource diff --git a/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlRS/MSFT_SqlRS.schema.mof b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlRS/MSFT_SqlRS.schema.mof new file mode 100644 index 000000000..2c0a1669e --- /dev/null +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlRS/MSFT_SqlRS.schema.mof @@ -0,0 +1,13 @@ +[ClassVersion("1.0.0.0"), FriendlyName("SqlRS")] +class MSFT_SqlRS : OMI_BaseResource +{ + [Key, Description("Name of the SQL Server Reporting Services instance to be configured.")] String InstanceName; + [Required, Description("Name of the SQL Server to host the Reporting Service database.")] String DatabaseServerName; + [Required, Description("Name of the SQL Server instance to host the Reporting Service database.")] String DatabaseInstanceName; + [Write, Description("Report Server Web Service virtual directory. Optional.")] String ReportServerVirtualDirectory; + [Write, Description("Report Manager/Report Web App virtual directory name. Optional.")] String ReportsVirtualDirectory; + [Write, Description("Report Server URL reservations. Optional. If not specified, 'http://+:80' URL reservation will be used.")] String ReportServerReservedUrl[]; + [Write, Description("Report Manager/Report Web App URL reservations. Optional. If not specified, 'http://+:80' URL reservation will be used.")] String ReportsReservedUrl[]; + [Write, Description("If connections to the Reporting Services must use SSL. If this parameter is not assigned a value, the default is that Reporting Services does not use SSL.")] Boolean UseSsl; + [Read, Description("Is the Reporting Services instance initialized.")] Boolean IsInitialized; +}; diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerScript/MSFT_xSQLServerScript.psm1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlScript/MSFT_SqlScript.psm1 similarity index 69% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerScript/MSFT_xSQLServerScript.psm1 rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlScript/MSFT_SqlScript.psm1 index 75b23494f..0e61201e6 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerScript/MSFT_xSQLServerScript.psm1 +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlScript/MSFT_SqlScript.psm1 @@ -1,5 +1,5 @@ -$script:currentPath = Split-Path -Path $MyInvocation.MyCommand.Path -Parent -Import-Module -Name (Join-Path -Path (Split-Path -Path (Split-Path -Path $script:currentPath -Parent) -Parent) -ChildPath 'xSQLServerHelper.psm1') +$script:currentPath = Split-Path -Path $MyInvocation.MyCommand.Path -Parent +Import-Module -Name (Join-Path -Path (Split-Path -Path (Split-Path -Path $script:currentPath -Parent) -Parent) -ChildPath 'SqlServerDscHelper.psm1') <# .SYNOPSIS @@ -19,7 +19,7 @@ Import-Module -Name (Join-Path -Path (Split-Path -Path (Split-Path -Path $script .PARAMETER TestFilePath Path to the T-SQL file that will perform Test action. Any script that does not throw an error or returns null is evaluated to true. - The cmdlet Invoke-SqlCmd treats T-SQL Print statements as verbose text, and will not cause the test to return false. + The cmdlet Invoke-Sqlcmd treats T-SQL Print statements as verbose text, and will not cause the test to return false. .PARAMETER Credential The credentials to authenticate with, using SQL Authentication. To authenticate using Windows Authentication, assign the credentials @@ -27,10 +27,14 @@ Import-Module -Name (Join-Path -Path (Split-Path -Path (Split-Path -Path $script then SYSTEM account will be used to authenticate using Windows Authentication. .PARAMETER Variable - Specifies, as a string array, a sqlcmd scripting variable for use in the sqlcmd script, and sets a value for the variable. + Specifies, as a string array, a Invoke-Sqlcmd scripting variable for use in the Invoke-Sqlcmd script, and sets a value for the variable. Use a Windows PowerShell array to specify multiple variables and their values. For more information how to use this, please go to the help documentation for [Invoke-Sqlcmd](https://technet.microsoft.com/en-us/library/mt683370.aspx). + .PARAMETER QueryTimeout + Specifies, as an integer, the number of seconds after which the T-SQL script execution will time out. + In some SQL Server versions there is a bug in Invoke-Sqlcmd where the normal default value 0 (no timeout) is not respected and the default value is incorrectly set to 30 seconds. + .OUTPUTS Hash table containing key 'GetResult' which holds the value of the result from the SQL script that was ran from the parameter 'GetFilePath'. #> @@ -56,27 +60,34 @@ function Get-TargetResource [System.String] $TestFilePath, + [Parameter()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential, + [Parameter()] + [System.UInt32] + $QueryTimeout, + + [Parameter()] [System.String[]] $Variable ) $result = Invoke-SqlScript -ServerInstance $ServerInstance -SqlScriptPath $GetFilePath ` - -Credential $Credential -Variable $Variable -ErrorAction Stop + -Credential $Credential -Variable $Variable -QueryTimeout $QueryTimeout -ErrorAction Stop $getResult = Out-String -InputObject $result $returnValue = @{ ServerInstance = [System.String] $ServerInstance - SetFilePath = [System.String] $SetFilePath - GetFilePath = [System.String] $GetFilePath - TestFilePath = [System.String] $TestFilePath - Username = [System.Object] $Credential - Variable = [System.String[]] $Variable - GetResult = [System.String[]] $getresult + SetFilePath = [System.String] $SetFilePath + GetFilePath = [System.String] $GetFilePath + TestFilePath = [System.String] $TestFilePath + Credential = [System.Object] $Credential + QueryTimeout = [System.UInt32] $QueryTimeout + Variable = [System.String[]] $Variable + GetResult = [System.String[]] $getResult } $returnValue @@ -100,15 +111,19 @@ function Get-TargetResource .PARAMETER TestFilePath Path to the T-SQL file that will perform Test action. Any script that does not throw an error or returns null is evaluated to true. - The cmdlet Invoke-SqlCmd treats T-SQL Print statements as verbose text, and will not cause the test to return false. + The cmdlet Invoke-Sqlcmd treats T-SQL Print statements as verbose text, and will not cause the test to return false. .PARAMETER Credential The credentials to authenticate with, using SQL Authentication. To authenticate using Windows Authentication, assign the credentials to the built-in parameter `PsDscRunAsCredential`. If both parameters `Credential` and `PsDscRunAsCredential` are not assigned, then SYSTEM account will be used to authenticate using Windows Authentication. + .PARAMETER QueryTimeout + Specifies, as an integer, the number of seconds after which the T-SQL script execution will time out. + In some SQL Server versions there is a bug in Invoke-Sqlcmd where the normal default value 0 (no timeout) is not respected and the default value is incorrectly set to 30 seconds. + .PARAMETER Variable - Specifies, as a string array, a sqlcmd scripting variable for use in the sqlcmd script, and sets a value for the variable. + Specifies, as a string array, a Invoke-Sqlcmd scripting variable for use in the Invoke-Sqlcmd script, and sets a value for the variable. Use a Windows PowerShell array to specify multiple variables and their values. For more information how to use this, please go to the help documentation for [Invoke-Sqlcmd](https://technet.microsoft.com/en-us/library/mt683370.aspx). #> @@ -133,16 +148,22 @@ function Set-TargetResource [System.String] $TestFilePath, + [Parameter()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential, + [Parameter()] + [System.UInt32] + $QueryTimeout, + + [Parameter()] [System.String[]] $Variable ) Invoke-SqlScript -ServerInstance $ServerInstance -SqlScriptPath $SetFilePath ` - -Credential $Credential -Variable $Variable -ErrorAction Stop + -Credential $Credential -Variable $Variable -QueryTimeout $QueryTimeout -ErrorAction Stop } <# @@ -163,15 +184,19 @@ function Set-TargetResource .PARAMETER TestFilePath Path to the T-SQL file that will perform Test action. Any script that does not throw an error or returns null is evaluated to true. - The cmdlet Invoke-SqlCmd treats T-SQL Print statements as verbose text, and will not cause the test to return false. + The cmdlet Invoke-Sqlcmd treats T-SQL Print statements as verbose text, and will not cause the test to return false. .PARAMETER Credential The credentials to authenticate with, using SQL Authentication. To authenticate using Windows Authentication, assign the credentials to the built-in parameter `PsDscRunAsCredential`. If both parameters `Credential` and `PsDscRunAsCredential` are not assigned, then SYSTEM account will be used to authenticate using Windows Authentication. + .PARAMETER QueryTimeout + Specifies, as an integer, the number of seconds after which the T-SQL script execution will time out. + In some SQL Server versions there is a bug in Invoke-Sqlcmd where the normal default value 0 (no timeout) is not respected and the default value is incorrectly set to 30 seconds. + .PARAMETER Variable - Specifies, as a string array, a sqlcmd scripting variable for use in the sqlcmd script, and sets a value for the variable. + Specifies, as a string array, a Invoke-Sqlcmd scripting variable for use in the Invoke-Sqlcmd script, and sets a value for the variable. Use a Windows PowerShell array to specify multiple variables and their values. For more information how to use this, please go to the help documentation for [Invoke-Sqlcmd](https://technet.microsoft.com/en-us/library/mt683370.aspx). @@ -198,10 +223,16 @@ function Test-TargetResource [System.String] $TestFilePath, + [Parameter()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential, + [Parameter()] + [System.UInt32] + $QueryTimeout, + + [Parameter()] [System.String[]] $Variable ) @@ -209,9 +240,9 @@ function Test-TargetResource try { $result = Invoke-SqlScript -ServerInstance $ServerInstance -SqlScriptPath $TestFilePath ` - -Credential $Credential -Variable $Variable -ErrorAction Stop + -Credential $Credential -Variable $Variable -QueryTimeout $QueryTimeout -ErrorAction Stop - if($null -eq $result) + if ($null -eq $result) { return $true } @@ -239,12 +270,16 @@ function Test-TargetResource Path to SQL script file that will be executed. .PARAMETER Credential - The credentials to use to authenticate using SQL Authentication. To authenticate using Windows Authentication, assing the credentials + The credentials to use to authenticate using SQL Authentication. To authenticate using Windows Authentication, assign the credentials to the built-in parameter 'PsDscRunAsCredential'. If both parameters 'Credential' and 'PsDscRunAsCredential' are not assigned, then the SYSTEM account will be used to authenticate using Windows Authentication. + .PARAMETER QueryTimeout + Specifies, as an integer, the number of seconds after which the T-SQL script execution will time out. + In some SQL Server versions there is a bug in Invoke-Sqlcmd where the normal default value 0 (no timeout) is not respected and the default value is incorrectly set to 30 seconds. + .PARAMETER Variable - Creates a sqlcmd scripting variable for use in the sqlcmd script, and sets a value for the variable. + Creates a Invoke-Sqlcmd scripting variable for use in the Invoke-Sqlcmd script, and sets a value for the variable. #> function Invoke-SqlScript { @@ -258,24 +293,30 @@ function Invoke-SqlScript [System.String] $SqlScriptPath, + [Parameter()] [System.Management.Automation.PSCredential] [System.Management.Automation.Credential()] $Credential, + [Parameter()] + [System.UInt32] + $QueryTimeout, + + [Parameter()] [System.String[]] $Variable ) Import-SQLPSModule - if($null -ne $Credential) + if ($null -ne $Credential) { - $null = $PSBoundParameters.Add("Username", $Credential.UserName) - $null = $PSBoundParameters.Add("Password", $Credential.GetNetworkCredential().password) + $null = $PSBoundParameters.Add('Username', $Credential.UserName) + $null = $PSBoundParameters.Add('Password', $Credential.GetNetworkCredential().Password) } - $null = $PSBoundParameters.Remove("Credential") - $null = $PSBoundParameters.Remove("SqlScriptPath") + $null = $PSBoundParameters.Remove('Credential') + $null = $PSBoundParameters.Remove('SqlScriptPath') Invoke-Sqlcmd -InputFile $SqlScriptPath @PSBoundParameters } diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerScript/MSFT_xSQLServerScript.Schema.mof b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlScript/MSFT_SqlScript.schema.mof similarity index 61% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerScript/MSFT_xSQLServerScript.Schema.mof rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlScript/MSFT_SqlScript.schema.mof index 275ccd78c..3627db5b2 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerScript/MSFT_xSQLServerScript.Schema.mof +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlScript/MSFT_SqlScript.schema.mof @@ -1,11 +1,12 @@ -[ClassVersion("1.0.0.0"), FriendlyName("xSQLServerScript")] -class MSFT_xSQLServerScript : OMI_BaseResource +[ClassVersion("1.0.0.0"), FriendlyName("SqlScript")] +class MSFT_SqlScript : OMI_BaseResource { [Key, Description("The name of an instance of the Database Engine. For a default instance, only specify the computer name. For a named instance, use the format ComputerName\\InstanceName")] String ServerInstance; [Key, Description("Path to the T-SQL file that will perform Set action.")] String SetFilePath; [Key, Description("Path to the T-SQL file that will perform Get action. Any values returned by the T-SQL queries will also be returned by the cmdlet Get-DscConfiguration through the 'GetResult' property.")] String GetFilePath; - [Key, Description("Path to the T-SQL file that will perform Test action. Any script that does not throw an error or returns null is evaluated to true. The cmdlet Invoke-SqlCmd treats T-SQL Print statements as verbose text, and will not cause the test to return false.")] String TestFilePath; + [Key, Description("Path to the T-SQL file that will perform Test action. Any script that does not throw an error or returns null is evaluated to true. The cmdlet Invoke-Sqlcmd treats T-SQL Print statements as verbose text, and will not cause the test to return false.")] String TestFilePath; [Write, EmbeddedInstance("MSFT_Credential"), Description("The credentials to authenticate with, using SQL Authentication. To authenticate using Windows Authentication, assign the credentials to the built-in parameter 'PsDscRunAsCredential'. If both parameters 'Credential' and 'PsDscRunAsCredential' are not assigned, then SYSTEM account will be used to authenticate using Windows Authentication.")] String Credential; - [Write, Description("Specifies, as a string array, a sqlcmd scripting variable for use in the sqlcmd script, and sets a value for the variable. Use a Windows PowerShell array to specify multiple variables and their values. For more information how to use this, please go to the help documentation for Invoke-Sqlcmd.")] String Variable[]; + [Write, Description("Specifies, as a string array, a scripting variable for use in the sql script, and sets a value for the variable. Use a Windows PowerShell array to specify multiple variables and their values. For more information how to use this, please go to the help documentation for [Invoke-Sqlcmd](https://technet.microsoft.com/en-us/library/mt683370.aspx)")] String Variable[]; + [Write, Description("Specifies, as an integer, the number of seconds after which the T-SQL script execution will time out. In some SQL Server versions there is a bug in Invoke-Sqlcmd where the normal default value 0 (no timeout) is not respected and the default value is incorrectly set to 30 seconds.")] UInt32 QueryTimeout; [Read, Description("Contains the values returned from the T-SQL script provided in the parameter 'GetFilePath' when cmdlet Get-DscConfiguration is run.")] String GetResult[]; }; diff --git a/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerConfiguration/MSFT_SqlServerConfiguration.psm1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerConfiguration/MSFT_SqlServerConfiguration.psm1 new file mode 100644 index 000000000..e67497ce5 --- /dev/null +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerConfiguration/MSFT_SqlServerConfiguration.psm1 @@ -0,0 +1,267 @@ +Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) ` + -ChildPath 'SqlServerDscHelper.psm1') ` + -Force + +Import-Module -Name (Join-Path -Path (Split-Path -Path $PSScriptRoot -Parent) ` + -ChildPath 'CommonResourceHelper.psm1') + +$script:localizedData = Get-LocalizedData -ResourceName 'MSFT_SqlServerConfiguration' + +<# + .SYNOPSIS + Gets the current value of a SQL configuration option + + .PARAMETER ServerName + Hostname of the SQL Server to be configured + + .PARAMETER InstanceName + Name of the SQL instance to be configured. Default is 'MSSQLSERVER' + + .PARAMETER OptionName + The name of the SQL configuration option to be checked + + .PARAMETER OptionValue + The desired value of the SQL configuration option + + .PARAMETER RestartService + *** Not used in this function *** + Determines whether the instance should be restarted after updating the + configuration option. + + .PARAMETER RestartTimeout + *** Not used in this function *** + The length of time, in seconds, to wait for the service to restart. Default + is 120 seconds. +#> +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param( + [Parameter(Mandatory = $true)] + [System.String] + $ServerName, + + [Parameter(Mandatory = $true)] + [System.String] + $InstanceName, + + [Parameter(Mandatory = $true)] + [System.String] + $OptionName, + + [Parameter(Mandatory = $true)] + [System.Int32] + $OptionValue, + + [Parameter()] + [System.Boolean] + $RestartService = $false, + + [Parameter()] + [System.UInt32] + $RestartTimeout = 120 + ) + + $sql = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName + + # Get the current value of the configuration option. + $option = $sql.Configuration.Properties | Where-Object { $_.DisplayName -eq $OptionName } + + if (-not $option) + { + $errorMessage = $script:localizedData.ConfigurationOptionNotFound -f $OptionName + New-InvalidArgumentException -ArgumentName 'OptionName' -Message $errorMessage + } + + Write-Verbose -Message ( + $script:localizedData.CurrentOptionValue ` + -f $OptionName, $option.ConfigValue + ) + + return @{ + ServerName = $ServerName + InstanceName = $InstanceName + OptionName = $option.DisplayName + OptionValue = $option.ConfigValue + RestartService = $RestartService + RestartTimeout = $RestartTimeout + } +} + +<# + .SYNOPSIS + Sets the value of a SQL configuration option + + .PARAMETER ServerName + Hostname of the SQL Server to be configured + + .PARAMETER InstanceName + Name of the SQL instance to be configured. Default is 'MSSQLSERVER' + + .PARAMETER OptionName + The name of the SQL configuration option to be set + + .PARAMETER OptionValue + The desired value of the SQL configuration option + + .PARAMETER RestartService + Determines whether the instance should be restarted after updating the + configuration option + + .PARAMETER RestartTimeout + The length of time, in seconds, to wait for the service to restart. Default + is 120 seconds. +#> +function Set-TargetResource +{ + [CmdletBinding()] + param( + [Parameter(Mandatory = $true)] + [System.String] + $ServerName, + + [Parameter(Mandatory = $true)] + [System.String] + $InstanceName, + + [Parameter(Mandatory = $true)] + [System.String] + $OptionName, + + [Parameter(Mandatory = $true)] + [System.Int32] + $OptionValue, + + [Parameter()] + [System.Boolean] + $RestartService = $false, + + [Parameter()] + [System.UInt32] + $RestartTimeout = 120 + ) + + $sql = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName + + # Get the current value of the configuration option. + $option = $sql.Configuration.Properties | Where-Object { $_.DisplayName -eq $OptionName } + + if (-not $option) + { + $errorMessage = $script:localizedData.ConfigurationOptionNotFound -f $OptionName + New-InvalidArgumentException -ArgumentName 'OptionName' -Message $errorMessage + } + + $option.ConfigValue = $OptionValue + $sql.Configuration.Alter() + + Write-Verbose -Message ( + $script:localizedData.ConfigurationValueUpdated ` + -f $OptionName, $OptionValue + ) + + if ($option.IsDynamic -eq $true) + { + Write-Verbose -Message $script:localizedData.NoRestartNeeded + } + elseif (($option.IsDynamic -eq $false) -and ($RestartService -eq $true)) + { + Write-Verbose -Message ( + $script:localizedData.AutomaticRestart ` + -f $ServerName, $InstanceName + ) + + Restart-SqlService -SQLServer $ServerName -SQLInstanceName $InstanceName -Timeout $RestartTimeout + } + else + { + Write-Warning -Message ( + $script:localizedData.ConfigurationRestartRequired ` + -f $OptionName, $OptionValue, $ServerName, $InstanceName + ) + } +} + +<# + .SYNOPSIS + Determines whether a SQL configuration option value is properly set + + .PARAMETER ServerName + Hostname of the SQL Server to be configured + + .PARAMETER InstanceName + Name of the SQL instance to be configured. Default is 'MSSQLSERVER' + + .PARAMETER OptionName + The name of the SQL configuration option to be tested + + .PARAMETER OptionValue + The desired value of the SQL configuration option + + .PARAMETER RestartService + *** Not used in this function *** + Determines whether the instance should be restarted after updating the + configuration option + + .PARAMETER RestartTimeout + *** Not used in this function *** + The length of time, in seconds, to wait for the service to restart. Default + is 120 seconds. +#> +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param( + [Parameter(Mandatory = $true)] + [System.String] + $ServerName, + + [Parameter(Mandatory = $true)] + [System.String] + $InstanceName, + + [Parameter(Mandatory = $true)] + [System.String] + $OptionName, + + [Parameter(Mandatory = $true)] + [System.Int32] + $OptionValue, + + [Parameter()] + [System.Boolean] + $RestartService = $false, + + [Parameter()] + [System.UInt32] + $RestartTimeout = 120 + ) + + # Get the current value of the configuration option. + $getTargetResourceResult = Get-TargetResource @PSBoundParameters + + if ($getTargetResourceResult.OptionValue -eq $OptionValue) + { + Write-Verbose -Message ( + $script:localizedData.InDesiredState ` + -f $OptionName + ) + + $result = $true + } + else + { + Write-Verbose -Message ( + $script:localizedData.NotInDesiredState ` + -f $OptionName, $OptionValue, $getTargetResourceResult.OptionValue + ) + + $result = $false + } + + return $result +} + +Export-ModuleMember -Function *-TargetResource diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerConfiguration/MSFT_xSQLServerConfiguration.schema.mof b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerConfiguration/MSFT_SqlServerConfiguration.schema.mof similarity index 65% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerConfiguration/MSFT_xSQLServerConfiguration.schema.mof rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerConfiguration/MSFT_SqlServerConfiguration.schema.mof index e90976a76..d02ee2903 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerConfiguration/MSFT_xSQLServerConfiguration.schema.mof +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerConfiguration/MSFT_SqlServerConfiguration.schema.mof @@ -1,10 +1,10 @@ -[ClassVersion("1.0.0.0"), FriendlyName("xSQLServerConfiguration")] -class MSFT_xSQLServerConfiguration : OMI_BaseResource +[ClassVersion("1.0.0.0"), FriendlyName("SqlServerConfiguration")] +class MSFT_SqlServerConfiguration : OMI_BaseResource { - [Key, Description("The hostname of the SQL Server to be configured.")] String SQLServer; - [Key, Description("Name of the SQL instance to be configured.")] String SQLInstanceName; + [Key, Description("The hostname of the SQL Server to be configured.")] String ServerName; + [Key, Description("Name of the SQL instance to be configured.")] String InstanceName; [Key, Description("The name of the SQL configuration option to be checked.")] String OptionName; - [Required, Description("The desired value of the SQL configuration option.")] Sint32 OptionValue; + [Required, Description("The desired value of the SQL configuration option.")] SInt32 OptionValue; [Write, Description("Determines whether the instance should be restarted after updating the configuration option.")] Boolean RestartService; - [Write, Description("The length of time, in seconds, to wait for the service to restart. Default is 120 seconds.")] Sint32 RestartTimeout; + [Write, Description("The length of time, in seconds, to wait for the service to restart. Default is 120 seconds.")] UInt32 RestartTimeout; }; diff --git a/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerConfiguration/en-US/MSFT_SqlServerConfiguration.strings.psd1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerConfiguration/en-US/MSFT_SqlServerConfiguration.strings.psd1 new file mode 100644 index 000000000..f1f74e1f6 --- /dev/null +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerConfiguration/en-US/MSFT_SqlServerConfiguration.strings.psd1 @@ -0,0 +1,12 @@ +# Localized resources for SqlServerConfiguration + +ConvertFrom-StringData @' + CurrentOptionValue = Configuration option '{0}' has a current value of '{1}'. + ConfigurationValueUpdated = Configuration option '{0}' has been updated to value '{1}'. + AutomaticRestart = A restart of SQL Server is required for the change to take effect. Initiating automatic restart of the SQL Server instance {0}//{1}. + ConfigurationOptionNotFound = Specified option '{0}' could not be found. + ConfigurationRestartRequired = Configuration option '{0}' has been updated to value '{1}', but a manual restart of SQL Server instance {2}//{3} is required for it to take effect. + NotInDesiredState = Configuration option '{0}' is not in desired state. Expected '{1}', but was '{2}'. + InDesiredState = Configuration option '{0}' is in desired state. + NoRestartNeeded = The option was changed without the need to restart the SQL Server instance. +'@ diff --git a/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerDatabaseMail/MSFT_SqlServerDatabaseMail.psm1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerDatabaseMail/MSFT_SqlServerDatabaseMail.psm1 new file mode 100644 index 000000000..f1a304db4 --- /dev/null +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerDatabaseMail/MSFT_SqlServerDatabaseMail.psm1 @@ -0,0 +1,732 @@ +Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) ` + -ChildPath 'SqlServerDscHelper.psm1') ` + -Force + +Import-Module -Name (Join-Path -Path (Split-Path -Path $PSScriptRoot -Parent) ` + -ChildPath 'CommonResourceHelper.psm1') + +$script:localizedData = Get-LocalizedData -ResourceName 'MSFT_SqlServerDatabaseMail' + +<# + .SYNOPSIS + Returns the current state of the Database Mail configuration. + + .PARAMETER ServerName + The hostname of the SQL Server to be configured. + Defaults to $env:COMPUTERNAME. + + .PARAMETER InstanceName + The name of the SQL instance to be configured. + + .PARAMETER AccountName + The name of the Database Mail account. + + .PARAMETER EmailAddress + The e-mail address from which mail will originate. + + .PARAMETER MailServerName + The fully qualified domain name of the mail server name to which e-mail are + sent. + + .PARAMETER ProfileName + The profile name of the Database Mail. +#> +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter()] + [System.String] + $ServerName = $env:COMPUTERNAME, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $InstanceName, + + [Parameter(Mandatory = $true)] + [System.String] + $AccountName, + + [Parameter(Mandatory = $true)] + [System.String] + $EmailAddress, + + [Parameter(Mandatory = $true)] + [System.String] + $MailServerName, + + [Parameter(Mandatory = $true)] + [System.String] + $ProfileName + ) + + $returnValue = @{ + Ensure = 'Absent' + ServerName = $ServerName + InstanceName = $InstanceName + AccountName = $null + EmailAddress = $null + MailServerName = $null + LoggingLevel = $null + ProfileName = $null + DisplayName = $null + ReplyToAddress = $null + Description = $null + TcpPort = $null + } + + Write-Verbose -Message ( + $script:localizedData.ConnectToSqlInstance ` + -f $ServerName, $InstanceName + ) + + $sqlServerObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName + + if ($sqlServerObject) + { + $databaseMailEnabledRunValue = $sqlServerObject.Configuration.DatabaseMailEnabled.RunValue + if ($databaseMailEnabledRunValue -eq 1) + { + Write-Verbose -Message ( + $script:localizedData.DatabaseMailEnabled ` + -f $databaseMailEnabledRunValue + ) + + $databaseMail = $sqlServerObject.Mail + + $databaseMailAccount = $databaseMail.Accounts | Where-Object -FilterScript { + $_.Name -eq $AccountName + } + + if ($databaseMailAccount) + { + Write-Verbose -Message ( + $script:localizedData.GetConfiguration ` + -f $AccountName + ) + + $loggingLevelText = switch ($databaseMail.ConfigurationValues['LoggingLevel'].Value) + { + 1 + { + 'Normal' + } + + 2 + { + 'Extended' + } + + 3 + { + 'Verbose' + } + } + + <# + AccountName exist so we set this as 'Present' regardless if + other properties are in desired state, the Test-TargetResource + function must handle that. + #> + $returnValue['Ensure'] = 'Present' + $returnValue['LoggingLevel'] = $loggingLevelText + $returnValue['AccountName'] = $databaseMailAccount.Name + $returnValue['EmailAddress'] = $databaseMailAccount.EmailAddress + $returnValue['DisplayName'] = $databaseMailAccount.DisplayName + $returnValue['ReplyToAddress'] = $databaseMailAccount.ReplyToAddress + + # Currently only the first mail server is handled. + $mailServer = $databaseMailAccount.MailServers | Select-Object -First 1 + + $returnValue['MailServerName'] = $mailServer.Name + $returnValue['TcpPort'] = $mailServer.Port + + # Currently only one profile is handled, so this make sure only the first string (profile name) is returned. + $returnValue['ProfileName'] = $databaseMail.Profiles | Select-Object -First 1 -ExpandProperty Name + + # SQL Server returns '' for Description property when value is not set. + if ($databaseMailAccount.Description -eq '') + { + # Convert empty value to $null + $returnValue['Description'] = $null + } + else + { + $returnValue['Description'] = $databaseMailAccount.Description + } + } + else + { + Write-Verbose -Message ( + $script:localizedData.AccountIsMissing ` + -f $AccountName + ) + } + } + else + { + Write-Verbose -Message ( + $script:localizedData.DatabaseMailDisabled + ) + } + } + + return $returnValue +} + +<# + .SYNOPSIS + Creates or removes the Database Mail configuration. + + .PARAMETER Ensure + Specifies the desired state of the Database Mail. + When set to 'Present', the Database Mail will be created. + When set to 'Absent', the Database Mail will be removed. + Default value is 'Present'. + + .PARAMETER ServerName + The hostname of the SQL Server to be configured. + Defaults to $env:COMPUTERNAME. + + .PARAMETER InstanceName + The name of the SQL instance to be configured. + + .PARAMETER AccountName + The name of the Database Mail account. + + .PARAMETER EmailAddress + The e-mail address from which mail will originate. + + .PARAMETER MailServerName + The fully qualified domain name of the mail server name to which e-mail are + sent. + + .PARAMETER ProfileName + The profile name of the Database Mail. + + .PARAMETER DisplayName + The display name of the outgoing mail server. Default value is the same + value assigned to parameter MailServerName. + + .PARAMETER ReplyToAddress + The e-mail address to which the receiver of e-mails will reply to. + Default value is the same e-mail address assigned to parameter EmailAddress. + + .PARAMETER Description + The description of the Database Mail. + + .PARAMETER LoggingLevel + The logging level that the Database Mail will use. If not specified the + default logging level is 'Extended'. { Normal | *Extended* | Verbose }. + + .PARAMETER TcpPort + The TCP port used for communication. Default value is port 25. + + .NOTES + Information about the different properties can be found here + https://docs.microsoft.com/en-us/sql/relational-databases/database-mail/configure-database-mail. + +#> +function Set-TargetResource +{ + [CmdletBinding()] + param + ( + [Parameter()] + [ValidateSet('Present', 'Absent')] + [System.String] + $Ensure = 'Present', + + [Parameter()] + [System.String] + $ServerName = $env:COMPUTERNAME, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $InstanceName, + + [Parameter(Mandatory = $true)] + [System.String] + $AccountName, + + [Parameter(Mandatory = $true)] + [System.String] + $EmailAddress, + + [Parameter(Mandatory = $true)] + [System.String] + $MailServerName, + + [Parameter(Mandatory = $true)] + [System.String] + $ProfileName, + + [Parameter()] + [System.String] + $DisplayName = $MailServerName, + + [Parameter()] + [System.String] + $ReplyToAddress = $EmailAddress, + + [Parameter()] + [System.String] + $Description, + + [Parameter()] + [System.String] + [ValidateSet('Normal', 'Extended', 'Verbose')] + $LoggingLevel, + + [Parameter()] + [System.UInt16] + $TcpPort = 25 + ) + + Write-Verbose -Message ( + $script:localizedData.ConnectToSqlInstance ` + -f $ServerName, $InstanceName + ) + + $sqlServerObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName + + if ($sqlServerObject) + { + if ($Ensure -eq 'Present') + { + + $databaseMailEnabledRunValue = $sqlServerObject.Configuration.DatabaseMailEnabled.RunValue + if ($databaseMailEnabledRunValue -eq 1) + { + $databaseMail = $sqlServerObject.Mail + + if ($PSBoundParameters.ContainsKey('LoggingLevel')) + { + $loggingLevelValue = switch ($LoggingLevel) + { + 'Normal' + { + 1 + } + + 'Extended' + { + 2 + } + + 'Verbose' + { + 3 + } + } + + $currentLoggingLevelValue = $databaseMail.ConfigurationValues['LoggingLevel'].Value + if ($loggingLevelValue -ne $currentLoggingLevelValue) + { + Write-Verbose -Message ( + $script:localizedData.ChangingLoggingLevel ` + -f $LoggingLevel, $loggingLevelValue + ) + + $databaseMail.ConfigurationValues['LoggingLevel'].Value = $loggingLevelValue + $databaseMail.ConfigurationValues['LoggingLevel'].Alter() + } + else + { + Write-Verbose -Message ( + $script:localizedData.CurrentLoggingLevel ` + -f $LoggingLevel, $loggingLevelValue + ) + } + } + + $databaseMailAccount = $databaseMail.Accounts | Where-Object -FilterScript { + $_.Name -eq $AccountName + } + + if (-not $databaseMailAccount) + { + Write-Verbose -Message ( + $script:localizedData.CreatingMailAccount ` + -f $AccountName + ) + + $databaseMailAccount = New-Object -TypeName Microsoft.SqlServer.Management.SMO.Mail.MailAccount -ArgumentList @($databaseMail, $AccountName) + $databaseMailAccount.Description = $Description + $databaseMailAccount.DisplayName = $DisplayName + $databaseMailAccount.EmailAddress = $EmailAddress + $databaseMailAccount.ReplyToAddress = $ReplyToAddress + $databaseMailAccount.Create() + + # The previous Create() method will always create a first mail server. + $mailServer = $databaseMailAccount.MailServers | Select-Object -First 1 + + if ($mailServer) + { + $mailServer.Rename($MailServerName) + + if ($PSBoundParameters.ContainsKey('TcpPort')) + { + $mailServer.Port = $TcpPort + } + + $mailServer.Alter() + } + } + else + { + Write-Verbose -Message ( + $script:localizedData.MailAccountExist ` + -f $AccountName + ) + + $currentDisplayName = $databaseMailAccount.DisplayName + if ($currentDisplayName -ne $DisplayName) + { + Write-Verbose -Message ( + $script:localizedData.UpdatingPropertyOfMailServer -f @( + $currentDisplayName + $DisplayName + $script:localizedData.MailServerPropertyDisplayName + ) + ) + + $databaseMailAccount.DisplayName = $DisplayName + $databaseMailAccount.Alter() + } + + $currentDescription = $databaseMailAccount.Description + if ($currentDescription -ne $Description) + { + Write-Verbose -Message ( + $script:localizedData.UpdatingPropertyOfMailServer -f @( + $currentDescription + $Description + $script:localizedData.MailServerPropertyDescription + ) + ) + + $databaseMailAccount.Description = $Description + $databaseMailAccount.Alter() + } + + $currentEmailAddress = $databaseMailAccount.EmailAddress + if ($currentEmailAddress -ne $EmailAddress) + { + Write-Verbose -Message ( + $script:localizedData.UpdatingPropertyOfMailServer -f @( + $currentEmailAddress + $EmailAddress + $script:localizedData.MailServerPropertyEmailAddress + ) + ) + + $databaseMailAccount.EmailAddress = $EmailAddress + $databaseMailAccount.Alter() + } + + $currentReplyToAddress = $databaseMailAccount.ReplyToAddress + if ($currentReplyToAddress -ne $ReplyToAddress) + { + Write-Verbose -Message ( + $script:localizedData.UpdatingPropertyOfMailServer -f @( + $currentReplyToAddress + $ReplyToAddress + $script:localizedData.MailServerPropertyReplyToEmailAddress + ) + ) + + $databaseMailAccount.ReplyToAddress = $ReplyToAddress + $databaseMailAccount.Alter() + } + + $mailServer = $databaseMailAccount.MailServers | Select-Object -First 1 + + $currentMailServerName = $mailServer.Name + if ($currentMailServerName -ne $MailServerName) + { + Write-Verbose -Message ( + $script:localizedData.UpdatingPropertyOfMailServer -f @( + $currentMailServerName + $MailServerName + $script:localizedData.MailServerPropertyServerName + ) + ) + + $mailServer.Rename($MailServerName) + $mailServer.Alter() + } + + $currentTcpPort = $mailServer.Port + if ($currentTcpPort -ne $TcpPort) + { + Write-Verbose -Message ( + $script:localizedData.UpdatingPropertyOfMailServer -f @( + $currentTcpPort + $TcpPort + $script:localizedData.MailServerPropertyTcpPort + ) + ) + + $mailServer.Port = $TcpPort + $mailServer.Alter() + } + } + + $databaseMailProfile = $databaseMail.Profiles | Where-Object -FilterScript { + $_.Name -eq $ProfileName + } + + if (-not $databaseMailProfile) + { + Write-Verbose -Message ( + $script:localizedData.CreatingMailProfile ` + -f $ProfileName + ) + + $databaseMailProfile = New-Object -TypeName Microsoft.SqlServer.Management.SMO.Mail.MailProfile -ArgumentList @($databaseMail, $ProfileName) + $databaseMailProfile.Description = $Description + $databaseMailProfile.Create() + + <# + A principal refers to a database user, a database role or + server role, an application role, or a SQL Server login. + You can add these types of users to the mail profile. + https://msdn.microsoft.com/en-us/library/ms208094.aspx + #> + $databaseMailProfile.AddPrincipal('public', $true) # $true means the default profile. + $databaseMailProfile.AddAccount($AccountName, 0) # Sequence number zero (0). + $databaseMailProfile.Alter() + } + else + { + Write-Verbose -Message ( + $script:localizedData.MailProfileExist ` + -f $ProfileName + ) + } + + if ($sqlServerObject.JobServer.AgentMailType -ne 'DatabaseMail' -or $sqlServerObject.JobServer.DatabaseMailProfile -ne $ProfileName) + { + Write-Verbose -Message ( + $script:localizedData.ConfigureSqlAgent + ) + + $sqlServerObject.JobServer.AgentMailType = 'DatabaseMail' + $sqlServerObject.JobServer.DatabaseMailProfile = $ProfileName + $sqlServerObject.JobServer.Alter() + } + else + { + Write-Verbose -Message ( + $script:localizedData.SqlAgentAlreadyConfigured + ) + } + } + else + { + $errorMessage = $script:localizedData.DatabaseMailDisabled + New-InvalidOperationException -Message $errorMessage + } + } + else + { + if ($sqlServerObject.JobServer.AgentMailType -eq 'DatabaseMail' -or $sqlServerObject.JobServer.DatabaseMailProfile -eq $ProfileName) + { + Write-Verbose -Message ( + $script:localizedData.RemovingSqlAgentConfiguration + ) + + $sqlServerObject.JobServer.AgentMailType = 'SqlAgentMail' + $sqlServerObject.JobServer.DatabaseMailProfile = $null + $sqlServerObject.JobServer.Alter() + } + + $databaseMail = $sqlServerObject.Mail + + $databaseMailProfile = $databaseMail.Profiles | Where-Object -FilterScript { + $_.Name -eq $ProfileName + } + + if ($databaseMailProfile) + { + Write-Verbose -Message ( + $script:localizedData.RemovingMailProfile ` + -f $ProfileName + ) + + $databaseMailProfile.Drop() + } + + $databaseMailAccount = $databaseMail.Accounts | Where-Object -FilterScript { + $_.Name -eq $AccountName + } + + if ($databaseMailAccount) + { + Write-Verbose -Message ( + $script:localizedData.RemovingMailAccount ` + -f $AccountName + ) + + $databaseMailAccount.Drop() + } + } + } +} + +<# + .SYNOPSIS + Determines if the Database Mail is in the desired state. + + .PARAMETER Ensure + Specifies the desired state of the Database Mail. + When set to 'Present', the Database Mail will be created. + When set to 'Absent', the Database Mail will be removed. + Default value is 'Present'. + + .PARAMETER ServerName + The hostname of the SQL Server to be configured. + Defaults to $env:COMPUTERNAME. + + .PARAMETER InstanceName + The name of the SQL instance to be configured. + + .PARAMETER AccountName + The name of the Database Mail account. + + .PARAMETER EmailAddress + The e-mail address from which mail will originate. + + .PARAMETER MailServerName + The fully qualified domain name of the mail server name to which e-mail are + sent. + + .PARAMETER ProfileName + The profile name of the Database Mail. + + .PARAMETER DisplayName + The display name of the outgoing mail server. Default value is the same + value assigned to parameter MailServerName. + + .PARAMETER ReplyToAddress + The e-mail address to which the receiver of e-mails will reply to. + Default value is the same e-mail address assigned to parameter EmailAddress. + + .PARAMETER Description + The description of the Database Mail. + + .PARAMETER LoggingLevel + The logging level that the Database Mail will use. If not specified the + default logging level is 'Extended'. { Normal | *Extended* | Verbose }. + + .PARAMETER TcpPort + The TCP port used for communication. Default value is port 25. +#> +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter()] + [ValidateSet('Present', 'Absent')] + [System.String] + $Ensure = 'Present', + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $InstanceName, + + [Parameter(Mandatory = $true)] + [System.String] + $AccountName, + + [Parameter()] + [System.String] + $ServerName = $env:COMPUTERNAME, + + [Parameter(Mandatory = $true)] + [System.String] + $EmailAddress, + + [Parameter(Mandatory = $true)] + [System.String] + $MailServerName, + + [Parameter(Mandatory = $true)] + [System.String] + $ProfileName, + + [Parameter()] + [System.String] + $DisplayName = $MailServerName, + + [Parameter()] + [System.String] + $ReplyToAddress = $EmailAddress, + + [Parameter()] + [System.String] + $Description, + + [Parameter()] + [System.String] + [ValidateSet('Normal', 'Extended', 'Verbose')] + $LoggingLevel, + + [Parameter()] + [System.UInt16] + $TcpPort = 25 + ) + + $getTargetResourceParameters = @{ + ServerName = $ServerName + InstanceName = $InstanceName + AccountName = $AccountName + EmailAddress = $EmailAddress + MailServerName = $MailServerName + ProfileName = $ProfileName + } + + $returnValue = $false + + $getTargetResourceResult = Get-TargetResource @getTargetResourceParameters + + Write-Verbose -Message ( + $script:localizedData.TestingConfiguration + ) + + if ($Ensure -eq 'Present') + { + $returnValue = Test-SQLDscParameterState ` + -CurrentValues $getTargetResourceResult ` + -DesiredValues $PSBoundParameters ` + -ValuesToCheck @( + 'AccountName' + 'EmailAddress' + 'MailServerName' + 'ProfileName' + 'Ensure' + 'ReplyToAddress' + 'TcpPort' + 'DisplayName' + 'Description' + 'LoggingLevel' + ) + } + else + { + if ($Ensure -eq $getTargetResourceResult.Ensure) + { + $returnValue = $true + } + } + + return $returnValue +} diff --git a/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerDatabaseMail/MSFT_SqlServerDatabaseMail.schema.mof b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerDatabaseMail/MSFT_SqlServerDatabaseMail.schema.mof new file mode 100644 index 000000000..35f803f30 --- /dev/null +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerDatabaseMail/MSFT_SqlServerDatabaseMail.schema.mof @@ -0,0 +1,16 @@ +[ClassVersion("1.0.0.0"), FriendlyName("SqlServerDatabaseMail")] +class MSFT_SqlServerDatabaseMail : OMI_BaseResource +{ + [Key, Description("The name of the Database Mail account.")] String AccountName; + [Key, Description("The name of the SQL instance to be configured.")] String InstanceName; + [Required, Description("The e-mail address from which mail will originate.")] String EmailAddress; + [Required, Description("The fully qualified domain name of the mail server name to which e-mail are sent.")] String MailServerName; + [Required, Description("The profile name of the Database Mail.")] String ProfileName; + [Write, Description("Specifies the desired state of the Database Mail. When set to 'Present', the Database Mail will be created. When set to 'Absent', the Database Mail will be removed. Default value is 'Present'."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; + [Write, Description("The hostname of the SQL Server to be configured. Defaults to $env:COMPUTERNAME.")] String ServerName; + [Write, Description("The display name of the outgoing mail server. Default value is the same value assigned to parameter MailServerName.")] String DisplayName; + [Write, Description("The e-mail address to which the receiver of e-mails will reply to. Default value is the same e-mail address assigned to parameter EmailAddress.")] String ReplyToAddress; + [Write, Description("The description of the Database Mail.")] String Description; + [Write, Description("The logging level that the Database Mail will use. If not specified the default logging level is 'Extended'."), ValueMap{"Normal","Extended","Verbose"}, Values{"Normal","Extended","Verbose"}] String LoggingLevel; + [Write, Description("The TCP port used for communication. Default value is port 25.")] UInt16 TcpPort; +}; diff --git a/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerDatabaseMail/en-US/MSFT_SqlServerDatabaseMail.strings.psd1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerDatabaseMail/en-US/MSFT_SqlServerDatabaseMail.strings.psd1 new file mode 100644 index 000000000..9f91e8726 --- /dev/null +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerDatabaseMail/en-US/MSFT_SqlServerDatabaseMail.strings.psd1 @@ -0,0 +1,33 @@ +<# + Localized resources for MSFT_SqlServerDatabaseMail + + Note: The named text strings MailServerProperty* are used in conjunction with + UpdatingPropertyOfMailServer to build a complete localized string. +#> + +ConvertFrom-StringData @' + ConnectToSqlInstance = Connecting to SQL Server instance '{0}\\{1}'. + DatabaseMailEnabled = SQL Server Database Mail is enabled. Database Mail XPs are set to {0}. + GetConfiguration = Account name '{0}' was found, returning the current state of the Database Mail configuration. + DatabaseMailDisabled = SQL Server Database Mail is disabled. Database Mail XPs are disabled. + AccountIsMissing = Account name '{0}' was not found. + ChangingLoggingLevel = Changing the SQL Server Database Mail logging level to '{0}' (value '{1}'). + CurrentLoggingLevel = SQL Server Database Mail logging level is '{0}' (value '{1}'). + CreatingMailAccount = Creating the mail account '{0}'. + MailAccountExist = Mail account '{0}' already exist. + UpdatingPropertyOfMailServer = Updating {2} of outgoing mail server. Current value is '{0}', expected '{1}'. + MailServerPropertyDisplayName = display name + MailServerPropertyDescription = description + MailServerPropertyEmailAddress = e-mail address + MailServerPropertyReplyToEmailAddress = reply to e-mail address + MailServerPropertyServerName = server name + MailServerPropertyTcpPort = TCP port + CreatingMailProfile = Creating a public default profile '{0}'. + MailProfileExist = The public default profile '{0}' already exist. + ConfigureSqlAgent = Configure the SQL Agent to use Database Mail. + SqlAgentAlreadyConfigured = The SQL Agent is already configured to use Database Mail. + TestingConfiguration = Determines if the Database Mail is in the desired state. + RemovingSqlAgentConfiguration = Configure the SQL Agent to not use Database Mail (changing it back to SQL Agent Mail). + RemovingMailProfile = Removing the public default profile '{0}'. + RemovingMailAccount = Removing the mail account '{0}'. +'@ diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerEndpoint/MSFT_xSQLServerEndpoint.psm1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerEndpoint/MSFT_SqlServerEndpoint.psm1 similarity index 82% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerEndpoint/MSFT_xSQLServerEndpoint.psm1 rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerEndpoint/MSFT_SqlServerEndpoint.psm1 index e72954b28..464a6dc0a 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerEndpoint/MSFT_xSQLServerEndpoint.psm1 +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerEndpoint/MSFT_SqlServerEndpoint.psm1 @@ -1,6 +1,6 @@ Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) ` - -ChildPath 'xSQLServerHelper.psm1') ` - -Force + -ChildPath 'SqlServerDscHelper.psm1') ` + -Force <# .SYNOPSIS Returns the current state of the endpoint. @@ -8,10 +8,10 @@ Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Pare .PARAMETER EndpointName The name of the endpoint. - .PARAMETER SQLServer + .PARAMETER ServerName The host name of the SQL Server to be configured. Default value is $env:COMPUTERNAME. - .PARAMETER SQLInstanceName + .PARAMETER InstanceName The name of the SQL instance to be configured. #> function Get-TargetResource @@ -26,26 +26,26 @@ function Get-TargetResource [Parameter()] [System.String] - $SQLServer = $env:COMPUTERNAME, + $ServerName = $env:COMPUTERNAME, [Parameter(Mandatory = $true)] [System.String] - $SQLInstanceName + $InstanceName ) $getTargetResourceReturnValues = @{ - SQLServer = $SQLServer - SQLInstanceName = $SQLInstanceName - Ensure = 'Absent' + ServerName = $ServerName + InstanceName = $InstanceName + Ensure = 'Absent' EndpointName = '' - Port = '' - IpAddress = '' + Port = '' + IpAddress = '' } - $sqlServerObject = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName + $sqlServerObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName if ($sqlServerObject) { - Write-Verbose -Message ('Connected to {0}\{1}' -f $SQLServer, $SQLInstanceName) + Write-Verbose -Message ('Connected to {0}\{1}' -f $ServerName, $InstanceName) $endpointObject = $sqlServerObject.Endpoints[$EndpointName] if ($endpointObject.Name -eq $EndpointName) @@ -53,8 +53,8 @@ function Get-TargetResource if ($sqlServerObject.Endpoints[$EndPointName].EndpointType -ne 'DatabaseMirroring') { throw New-TerminatingError -ErrorType EndpointFoundButWrongType ` - -FormatArgs @($EndpointName) ` - -ErrorCategory InvalidOperation + -FormatArgs @($EndpointName) ` + -ErrorCategory InvalidOperation } $getTargetResourceReturnValues.Ensure = 'Present' @@ -73,8 +73,8 @@ function Get-TargetResource else { throw New-TerminatingError -ErrorType NotConnectedToInstance ` - -FormatArgs @($SQLServer,$SQLInstanceName) ` - -ErrorCategory InvalidOperation + -FormatArgs @($ServerName, $InstanceName) ` + -ErrorCategory InvalidOperation } return $getTargetResourceReturnValues @@ -93,10 +93,10 @@ function Get-TargetResource .PARAMETER Port The network port the endpoint is listening on. Default value is 5022. - .PARAMETER SQLServer + .PARAMETER ServerName The host name of the SQL Server to be configured. Default value is $env:COMPUTERNAME. - .PARAMETER SQLInstanceName + .PARAMETER InstanceName The name of the SQL instance to be configured. .PARAMETER IpAddress @@ -112,7 +112,7 @@ function Set-TargetResource $EndpointName, [Parameter()] - [ValidateSet('Present','Absent')] + [ValidateSet('Present', 'Absent')] [System.String] $Ensure = 'Present', @@ -122,20 +122,20 @@ function Set-TargetResource [Parameter()] [System.String] - $SQLServer = $env:COMPUTERNAME, + $ServerName = $env:COMPUTERNAME, [Parameter(Mandatory = $true)] [System.String] - $SQLInstanceName, + $InstanceName, [Parameter()] [System.String] $IpAddress = '0.0.0.0' ) - $getTargetResourceResult = Get-TargetResource -EndpointName $EndpointName -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName + $getTargetResourceResult = Get-TargetResource -EndpointName $EndpointName -ServerName $ServerName -InstanceName $InstanceName - $sqlServerObject = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName + $sqlServerObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName if ($sqlServerObject) { if ($Ensure -eq 'Present' -and $getTargetResourceResult.Ensure -eq 'Absent') @@ -196,8 +196,8 @@ function Set-TargetResource else { throw New-TerminatingError -ErrorType NotConnectedToInstance ` - -FormatArgs @($SQLServer,$SQLInstanceName) ` - -ErrorCategory InvalidOperation + -FormatArgs @($ServerName, $InstanceName) ` + -ErrorCategory InvalidOperation } } @@ -214,10 +214,10 @@ function Set-TargetResource .PARAMETER Port The network port the endpoint is listening on. Default value is 5022. - .PARAMETER SQLServer + .PARAMETER ServerName The host name of the SQL Server to be configured. Default value is $env:COMPUTERNAME. - .PARAMETER SQLInstanceName + .PARAMETER InstanceName The name of the SQL instance to be configured. .PARAMETER IpAddress @@ -234,7 +234,7 @@ function Test-TargetResource $EndpointName, [Parameter()] - [ValidateSet('Present','Absent')] + [ValidateSet('Present', 'Absent')] [System.String] $Ensure = 'Present', @@ -244,28 +244,28 @@ function Test-TargetResource [Parameter()] [System.String] - $SQLServer = $env:COMPUTERNAME, + $ServerName = $env:COMPUTERNAME, [Parameter(Mandatory = $true)] [System.String] - $SQLInstanceName, + $InstanceName, [Parameter()] [System.String] $IpAddress = '0.0.0.0' ) - $getTargetResourceResult = Get-TargetResource -EndpointName $EndpointName -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName + $getTargetResourceResult = Get-TargetResource -EndpointName $EndpointName -ServerName $ServerName -InstanceName $InstanceName if ($getTargetResourceResult.Ensure -eq $Ensure) { $result = $true if ($getTargetResourceResult.Ensure -eq 'Present' ` - -and ( + -and ( $getTargetResourceResult.Port -ne $Port ` - -or $getTargetResourceResult.IpAddress -ne $IpAddress - ) + -or $getTargetResourceResult.IpAddress -ne $IpAddress ) + ) { $result = $false } diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerEndpoint/MSFT_xSQLServerEndpoint.schema.mof b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerEndpoint/MSFT_SqlServerEndpoint.schema.mof similarity index 75% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerEndpoint/MSFT_xSQLServerEndpoint.schema.mof rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerEndpoint/MSFT_SqlServerEndpoint.schema.mof index 737bb8dbf..05c85cfab 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerEndpoint/MSFT_xSQLServerEndpoint.schema.mof +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerEndpoint/MSFT_SqlServerEndpoint.schema.mof @@ -1,10 +1,10 @@ -[ClassVersion("1.0.0.0"), FriendlyName("xSQLServerEndpoint")] -class MSFT_xSQLServerEndpoint : OMI_BaseResource +[ClassVersion("1.0.0.0"), FriendlyName("SqlServerEndpoint")] +class MSFT_SqlServerEndpoint : OMI_BaseResource { [Key, Description("The name of the endpoint.")] String EndpointName; [Write, Description("If the endpoint should be present or absent. Default values is 'Present'."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; [Write, Description("The network port the endpoint is listening on. Default value is 5022.")] Uint16 Port; - [Write, Description("The host name of the SQL Server to be configured. Default value is $env:COMPUTERNAME.")] String SQLServer; - [Key, Description("The name of the SQL instance to be configured.")] String SQLInstanceName; + [Write, Description("The host name of the SQL Server to be configured. Default value is $env:COMPUTERNAME.")] String ServerName; + [Key, Description("The name of the SQL instance to be configured.")] String InstanceName; [Write, Description("The network IP address the endpoint is listening on. Default the endpoint will listen on any valid IP address.")] String IpAddress; }; diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerEndpointPermission/MSFT_xSQLServerEndpointPermission.psm1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerEndpointPermission/MSFT_SqlServerEndpointPermission.psm1 similarity index 83% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerEndpointPermission/MSFT_xSQLServerEndpointPermission.psm1 rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerEndpointPermission/MSFT_SqlServerEndpointPermission.psm1 index bfdd1f18a..1d2b104d9 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerEndpointPermission/MSFT_xSQLServerEndpointPermission.psm1 +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerEndpointPermission/MSFT_SqlServerEndpointPermission.psm1 @@ -1,6 +1,6 @@ -Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) ` - -ChildPath 'xSQLServerHelper.psm1') ` - -Force +Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) ` + -ChildPath 'SqlServerDscHelper.psm1') ` + -Force <# .SYNOPSIS Returns the current state of the permissions for the principal (login). @@ -8,7 +8,7 @@ .PARAMETER InstanceName The name of the SQL instance to be configured. - .PARAMETER NodeName + .PARAMETER ServerName The host name of the SQL Server to be configured. .PARAMETER Name @@ -29,7 +29,7 @@ function Get-TargetResource [Parameter(Mandatory = $true)] [System.String] - $NodeName, + $ServerName, [Parameter(Mandatory = $true)] [System.String] @@ -42,10 +42,10 @@ function Get-TargetResource try { - $sqlServerObject = Connect-SQL -SQLServer $NodeName -SQLInstanceName $InstanceName + $sqlServerObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName $endpointObject = $sqlServerObject.Endpoints[$Name] - if( $null -ne $endpointObject ) + if ( $null -ne $endpointObject ) { New-VerboseMessage -Message "Enumerating permissions for endpoint $Name" @@ -75,11 +75,11 @@ function Get-TargetResource return @{ InstanceName = [System.String] $InstanceName - NodeName = [System.String] $NodeName - Ensure = [System.String] $Ensure - Name = [System.String] $Name - Principal = [System.String] $Principal - Permission = [System.String] $Permission + ServerName = [System.String] $ServerName + Ensure = [System.String] $Ensure + Name = [System.String] $Name + Principal = [System.String] $Principal + Permission = [System.String] $Permission } } @@ -90,7 +90,7 @@ function Get-TargetResource .PARAMETER InstanceName The name of the SQL instance to be configured. - .PARAMETER NodeName + .PARAMETER ServerName The host name of the SQL Server to be configured. .PARAMETER Ensure @@ -116,10 +116,10 @@ function Set-TargetResource [Parameter(Mandatory = $true)] [System.String] - $NodeName, + $ServerName, [Parameter()] - [ValidateSet('Present','Absent')] + [ValidateSet('Present', 'Absent')] [System.String] $Ensure = 'Present', @@ -139,15 +139,15 @@ function Set-TargetResource $parameters = @{ InstanceName = [System.String] $InstanceName - NodeName = [System.String] $NodeName - Name = [System.String] $Name - Principal = [System.String] $Principal + ServerName = [System.String] $ServerName + Name = [System.String] $Name + Principal = [System.String] $Principal } $getTargetResourceResult = Get-TargetResource @parameters if ($getTargetResourceResult.Ensure -ne $Ensure) { - $sqlServerObject = Connect-SQL -SQLServer $NodeName -SQLInstanceName $InstanceName + $sqlServerObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName $endpointObject = $sqlServerObject.Endpoints[$Name] if ($null -ne $endpointObject) @@ -184,7 +184,7 @@ function Set-TargetResource .PARAMETER InstanceName The name of the SQL instance to be configured. - .PARAMETER NodeName + .PARAMETER ServerName The host name of the SQL Server to be configured. .PARAMETER Ensure @@ -211,10 +211,10 @@ function Test-TargetResource [Parameter(Mandatory = $true)] [System.String] - $NodeName, + $ServerName, [Parameter()] - [ValidateSet('Present','Absent')] + [ValidateSet('Present', 'Absent')] [System.String] $Ensure = 'Present', @@ -234,9 +234,9 @@ function Test-TargetResource $parameters = @{ InstanceName = [System.String] $InstanceName - NodeName = [System.String] $NodeName - Name = [System.String] $Name - Principal = [System.String] $Principal + ServerName = [System.String] $ServerName + Name = [System.String] $Name + Principal = [System.String] $Principal } New-VerboseMessage -Message "Testing state of endpoint permission for $Principal" diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerEndpointPermission/MSFT_xSQLServerEndpointPermission.schema.mof b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerEndpointPermission/MSFT_SqlServerEndpointPermission.schema.mof similarity index 80% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerEndpointPermission/MSFT_xSQLServerEndpointPermission.schema.mof rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerEndpointPermission/MSFT_SqlServerEndpointPermission.schema.mof index d50707093..c7b02df36 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerEndpointPermission/MSFT_xSQLServerEndpointPermission.schema.mof +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerEndpointPermission/MSFT_SqlServerEndpointPermission.schema.mof @@ -1,9 +1,9 @@ -[ClassVersion("1.0.0.0"), FriendlyName("xSQLServerEndpointPermission")] -class MSFT_xSQLServerEndpointPermission : OMI_BaseResource +[ClassVersion("1.0.0.0"), FriendlyName("SqlServerEndpointPermission")] +class MSFT_SqlServerEndpointPermission : OMI_BaseResource { [Key, Description("The name of the SQL instance to be configured.")] String InstanceName; - [Required, Description("The host name of the SQL Server to be configured.")] String NodeName; + [Required, Description("The host name of the SQL Server to be configured.")] String ServerName; [Write, Description("If the permission should be present or absent. Default value is 'Present'."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; [Required, Description("The name of the endpoint.")] String Name; [Key, Description("The login to which permission will be set.")] String Principal; diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerEndpointState/MSFT_xSQLServerEndpointState.psm1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerEndpointState/MSFT_SqlServerEndpointState.psm1 similarity index 80% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerEndpointState/MSFT_xSQLServerEndpointState.psm1 rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerEndpointState/MSFT_SqlServerEndpointState.psm1 index 55a630c1e..b1deecd0c 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerEndpointState/MSFT_xSQLServerEndpointState.psm1 +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerEndpointState/MSFT_SqlServerEndpointState.psm1 @@ -1,6 +1,6 @@ -Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) ` - -ChildPath 'xSQLServerHelper.psm1') ` - -Force +Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) ` + -ChildPath 'SqlServerDscHelper.psm1') ` + -Force <# .SYNOPSIS Returns the current state of an endpoint. @@ -8,7 +8,7 @@ .PARAMETER InstanceName The name of the SQL instance to be configured. - .PARAMETER NodeName + .PARAMETER ServerName The host name of the SQL Server to be configured. .PARAMETER Name @@ -26,7 +26,7 @@ function Get-TargetResource [Parameter()] [System.String] - $NodeName = $env:COMPUTERNAME, + $ServerName = $env:COMPUTERNAME, [Parameter(Mandatory = $true)] [System.String] @@ -37,7 +37,7 @@ function Get-TargetResource try { - $sqlServerObject = Connect-SQL -SQLServer $NodeName -SQLInstanceName $InstanceName + $sqlServerObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName $endpointObject = $sqlServerObject.Endpoints[$Name] if ($null -ne $endpointObject) @@ -56,9 +56,9 @@ function Get-TargetResource return @{ InstanceName = [System.String] $InstanceName - NodeName = [System.String] $NodeName - Name = [System.String] $Name - State = [System.String] $currentState + ServerName = [System.String] $ServerName + Name = [System.String] $Name + State = [System.String] $currentState } } @@ -69,7 +69,7 @@ function Get-TargetResource .PARAMETER InstanceName The name of the SQL instance to be configured. - .PARAMETER NodeName + .PARAMETER ServerName The host name of the SQL Server to be configured. .PARAMETER Name @@ -89,22 +89,22 @@ function Set-TargetResource [Parameter()] [System.String] - $NodeName = $env:COMPUTERNAME, + $ServerName = $env:COMPUTERNAME, [Parameter(Mandatory = $true)] [System.String] $Name, [Parameter()] - [ValidateSet('Started','Stopped','Disabled')] + [ValidateSet('Started', 'Stopped', 'Disabled')] [System.String] $State = 'Started' ) $parameters = @{ InstanceName = [System.String] $InstanceName - NodeName = [System.String] $NodeName - Name = [System.String] $Name + ServerName = [System.String] $ServerName + Name = [System.String] $Name } $getTargetResourceResult = Get-TargetResource @parameters @@ -114,13 +114,13 @@ function Set-TargetResource { New-VerboseMessage -Message ('Changing state of endpoint ''{0}''' -f $Name) - $sqlServerObject = Connect-SQL -SQLServer $NodeName -SQLInstanceName $InstanceName + $sqlServerObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName $endpointObject = $sqlServerObject.Endpoints[$Name] $setEndpointParams = @{ InputObject = $endpointObject - State = $State + State = $State } Set-SqlHADREndpoint @setEndpointParams -ErrorAction Stop | Out-Null @@ -143,7 +143,7 @@ function Set-TargetResource .PARAMETER InstanceName The name of the SQL instance to be configured. - .PARAMETER NodeName + .PARAMETER ServerName The host name of the SQL Server to be configured. .PARAMETER Name @@ -164,22 +164,22 @@ function Test-TargetResource [Parameter()] [System.String] - $NodeName = $env:COMPUTERNAME, + $ServerName = $env:COMPUTERNAME, [Parameter(Mandatory = $true)] [System.String] $Name, [Parameter()] - [ValidateSet('Started','Stopped','Disabled')] + [ValidateSet('Started', 'Stopped', 'Disabled')] [System.String] $State = 'Started' ) $parameters = @{ InstanceName = $InstanceName - NodeName = $NodeName - Name = $Name + ServerName = $ServerName + Name = $Name } New-VerboseMessage -Message "Testing state $State on endpoint '$Name'" diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerEndpointState/MSFT_xSQLServerEndpointState.schema.mof b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerEndpointState/MSFT_SqlServerEndpointState.schema.mof similarity index 70% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerEndpointState/MSFT_xSQLServerEndpointState.schema.mof rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerEndpointState/MSFT_SqlServerEndpointState.schema.mof index 14edfab02..61062db7b 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerEndpointState/MSFT_xSQLServerEndpointState.schema.mof +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerEndpointState/MSFT_SqlServerEndpointState.schema.mof @@ -1,8 +1,8 @@ -[ClassVersion("1.0.0.0"), FriendlyName("xSQLServerEndpointState")] -class MSFT_xSQLServerEndpointState : OMI_BaseResource +[ClassVersion("1.0.0.0"), FriendlyName("SqlServerEndpointState")] +class MSFT_SqlServerEndpointState : OMI_BaseResource { [Key, Description("The name of the SQL instance to be configured.")] String InstanceName; - [Write, Description("The host name of the SQL Server to be configured. Default value is $env:COMPUTERNAME.")] String NodeName; + [Write, Description("The host name of the SQL Server to be configured. Default value is $env:COMPUTERNAME.")] String ServerName; [Key, Description("The name of the endpoint.")] String Name; [Write, Description("The state of the endpoint. Valid states are Started, Stopped or Disabled. Default value is 'Started'."), ValueMap{"Started","Stopped","Disabled"}, Values{"Started","Stopped","Disabled"}] String State; }; diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerLogin/MSFT_xSQLServerLogin.psm1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerLogin/MSFT_SqlServerLogin.psm1 similarity index 77% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerLogin/MSFT_xSQLServerLogin.psm1 rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerLogin/MSFT_SqlServerLogin.psm1 index 3bbd95ae1..fb91dfe5f 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerLogin/MSFT_xSQLServerLogin.psm1 +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerLogin/MSFT_SqlServerLogin.psm1 @@ -1,6 +1,6 @@ Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) ` - -ChildPath 'xSQLServerHelper.psm1') ` - -Force + -ChildPath 'SqlServerDscHelper.psm1') ` + -Force <# .SYNOPSIS @@ -8,12 +8,12 @@ Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Pare .PARAMETER Name The name of the login to retrieve. - - .PARAMETER SQLServer + + .PARAMETER ServerName Hostname of the SQL Server to retrieve the login from. - - .PARAMETER SQLInstanceName - Name of the SQL instance to retrieve the login from. + + .PARAMETER InstanceName + Name of the SQL instance to retrieve the login from. #> function Get-TargetResource { @@ -27,17 +27,17 @@ function Get-TargetResource [Parameter(Mandatory = $true)] [System.String] - $SQLServer, + $ServerName, [Parameter(Mandatory = $true)] [System.String] - $SQLInstanceName + $InstanceName ) - - $serverObject = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName + + $serverObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName Write-Verbose 'Getting SQL logins' - New-VerboseMessage -Message "Getting the login '$Name' from '$SQLServer\$SQLInstanceName'" + New-VerboseMessage -Message "Getting the login '$Name' from '$ServerName\$InstanceName'" $login = $serverObject.Logins[$Name] @@ -50,21 +50,22 @@ function Get-TargetResource $Ensure = 'Absent' } - New-VerboseMessage -Message "The login '$Name' is $ensure from the '$SQLServer\$SQLInstanceName' instance." + New-VerboseMessage -Message "The login '$Name' is $ensure from the '$ServerName\$InstanceName' instance." $returnValue = @{ - Ensure = $Ensure - Name = $Name - LoginType = $login.LoginType - SQLServer = $SQLServer - SQLInstanceName = $SQLInstanceName + Ensure = $Ensure + Name = $Name + LoginType = $login.LoginType + ServerName = $ServerName + InstanceName = $InstanceName + Disabled = $login.IsDisabled } if ( $login.LoginType -eq 'SqlLogin' ) { - $returnValue.Add('LoginMustChangePassword',$login.MustChangePassword) - $returnValue.Add('LoginPasswordExpirationEnabled',$login.PasswordExpirationEnabled) - $returnValue.Add('LoginPasswordPolicyEnforced',$login.PasswordPolicyEnforced) + $returnValue.Add('LoginMustChangePassword', $login.MustChangePassword) + $returnValue.Add('LoginPasswordExpirationEnabled', $login.PasswordExpirationEnabled) + $returnValue.Add('LoginPasswordPolicyEnforced', $login.PasswordPolicyEnforced) } return $returnValue @@ -76,17 +77,17 @@ function Get-TargetResource .PARAMETER Ensure Specifies if the login to exist. Default is 'Present'. - + .PARAMETER Name The name of the login to retrieve. .PARAMETER LoginType The type of login to create. Default is 'WindowsUser' - - .PARAMETER SQLServer + + .PARAMETER ServerName Hostname of the SQL Server to create the login on. - - .PARAMETER SQLInstanceName + + .PARAMETER InstanceName Name of the SQL instance to create the login on. .PARAMETER LoginCredential @@ -100,6 +101,9 @@ function Get-TargetResource .PARAMETER LoginPasswordPolicyEnforced Specifies if the login password is required to conform to the password policy specified in the system security policy. Only applies to SQL Logins. Default is $true. + + .PARAMETER Disabled + Specifies if the login is disabled. Default is $false. #> function Set-TargetResource { @@ -130,31 +134,35 @@ function Set-TargetResource [Parameter(Mandatory = $true)] [System.String] - $SQLServer, + $ServerName, [Parameter(Mandatory = $true)] [System.String] - $SQLInstanceName, + $InstanceName, [Parameter()] [System.Management.Automation.PSCredential] $LoginCredential, [Parameter()] - [bool] + [System.Boolean] $LoginMustChangePassword = $true, [Parameter()] - [bool] + [System.Boolean] $LoginPasswordExpirationEnabled = $true, [Parameter()] - [bool] - $LoginPasswordPolicyEnforced = $true + [System.Boolean] + $LoginPasswordPolicyEnforced = $true, + + [Parameter()] + [System.Boolean] + $Disabled ) - - $serverObject = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName - + + $serverObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName + switch ( $Ensure ) { 'Present' @@ -164,19 +172,17 @@ function Set-TargetResource $login = $serverObject.Logins[$Name] if ( $login.LoginType -eq 'SqlLogin' ) - { - - + { if ( $login.PasswordExpirationEnabled -ne $LoginPasswordExpirationEnabled ) { - New-VerboseMessage -Message "Setting PasswordExpirationEnabled to '$LoginPasswordExpirationEnabled' for the login '$Name' on the '$SQLServer\$SQLInstanceName' instance." + New-VerboseMessage -Message "Setting PasswordExpirationEnabled to '$LoginPasswordExpirationEnabled' for the login '$Name' on the '$ServerName\$InstanceName' instance." $login.PasswordExpirationEnabled = $LoginPasswordExpirationEnabled Update-SQLServerLogin -Login $login } if ( $login.PasswordPolicyEnforced -ne $LoginPasswordPolicyEnforced ) { - New-VerboseMessage -Message "Setting PasswordPolicyEnforced to '$LoginPasswordPolicyEnforced' for the login '$Name' on the '$SQLServer\$SQLInstanceName' instance." + New-VerboseMessage -Message "Setting PasswordPolicyEnforced to '$LoginPasswordPolicyEnforced' for the login '$Name' on the '$ServerName\$InstanceName' instance." $login.PasswordPolicyEnforced = $LoginPasswordPolicyEnforced Update-SQLServerLogin -Login $login } @@ -184,14 +190,27 @@ function Set-TargetResource # Set the password if it is specified if ( $LoginCredential ) { - Set-SQLServerLoginPassword -Login $login -SecureString $LoginCredential.Password + Set-SQLServerLoginPassword -Login $login -SecureString $LoginCredential.Password + } + } + + if ( $PSBoundParameters.ContainsKey('Disabled') -and ($login.IsDisabled -ne $Disabled) ) + { + New-VerboseMessage -Message "Setting IsDisabled to '$Disabled' for the login '$Name' on the '$ServerName\$InstanceName' instance." + if ( $Disabled ) + { + $login.Disable() + } + else + { + $login.Enable() } } } else { # Some login types need additional work. These will need to be fleshed out more in the future - if ( @('Certificate','AsymmetricKey','ExternalUser','ExternalGroup') -contains $LoginType ) + if ( @('Certificate', 'AsymmetricKey', 'ExternalUser', 'ExternalGroup') -contains $LoginType ) { throw New-TerminatingError -ErrorType LoginTypeNotImplemented -FormatArgs $LoginType -ErrorCategory NotImplemented } @@ -200,10 +219,10 @@ function Set-TargetResource { throw New-TerminatingError -ErrorType LoginCredentialNotFound -FormatArgs $Name -ErrorCategory ObjectNotFound } - - New-VerboseMessage -Message "Adding the login '$Name' to the '$SQLServer\$SQLInstanceName' instance." - - $login = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Login -ArgumentList $serverObject,$Name + + New-VerboseMessage -Message "Adding the login '$Name' to the '$ServerName\$InstanceName' instance." + + $login = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Login -ArgumentList $serverObject, $Name $login.LoginType = $LoginType switch ($LoginType) @@ -213,9 +232,9 @@ function Set-TargetResource # Verify the instance is in Mixed authentication mode if ( $serverObject.LoginMode -notmatch 'Mixed|Integrated' ) { - throw New-TerminatingError -ErrorType IncorrectLoginMode -FormatArgs $SQLServer,$SQLInstanceName,$serverObject.LoginMode -ErrorCategory NotImplemented + throw New-TerminatingError -ErrorType IncorrectLoginMode -FormatArgs $ServerName, $InstanceName, $serverObject.LoginMode -ErrorCategory NotImplemented } - + $login.PasswordPolicyEnforced = $LoginPasswordPolicyEnforced $login.PasswordExpirationEnabled = $LoginPasswordExpirationEnabled if ( $LoginMustChangePassword ) @@ -227,7 +246,7 @@ function Set-TargetResource $LoginCreateOptions = [Microsoft.SqlServer.Management.Smo.LoginCreateOptions]::None } - New-SQLServerLogin -Login $login -LoginCreateOptions $LoginCreateOptions -SecureString $LoginCredential.Password -ErrorAction Stop + New-SQLServerLogin -Login $login -LoginCreateOptions $LoginCreateOptions -SecureString $LoginCredential.Password -ErrorAction Stop } default @@ -235,6 +254,12 @@ function Set-TargetResource New-SQLServerLogin -Login $login } } + + # we can only disable the login once it's been created + if ( $Disabled ) + { + $login.Disable() + } } } @@ -242,7 +267,7 @@ function Set-TargetResource { if ( $serverObject.Logins[$Name] ) { - New-VerboseMessage -Message "Dropping the login '$Name' from the '$SQLServer\$SQLInstanceName' instance." + New-VerboseMessage -Message "Dropping the login '$Name' from the '$ServerName\$InstanceName' instance." Remove-SQLServerLogin -Login $serverObject.Logins[$Name] } } @@ -255,17 +280,17 @@ function Set-TargetResource .PARAMETER Ensure Specifies if the login is supposed to exist. Default is 'Present'. - + .PARAMETER Name The name of the login. .PARAMETER LoginType The type of login. Default is 'WindowsUser' - - .PARAMETER SQLServer + + .PARAMETER ServerName Hostname of the SQL Server. - - .PARAMETER SQLInstanceName + + .PARAMETER InstanceName Name of the SQL instance. .PARAMETER LoginCredential @@ -279,6 +304,9 @@ function Set-TargetResource .PARAMETER LoginPasswordPolicyEnforced Specifies if the login password is required to conform to the password policy specified in the system security policy. Only applies to SQL Logins. Default is $true. + + .PARAMETER Disabled + Specifies if the login is disabled. Default is $false. #> function Test-TargetResource { @@ -309,43 +337,47 @@ function Test-TargetResource [Parameter(Mandatory = $true)] [System.String] - $SQLServer, + $ServerName, [Parameter(Mandatory = $true)] [System.String] - $SQLInstanceName, + $InstanceName, [Parameter()] [System.Management.Automation.PSCredential] $LoginCredential, [Parameter()] - [bool] + [System.Boolean] $LoginMustChangePassword = $true, [Parameter()] - [bool] + [System.Boolean] $LoginPasswordExpirationEnabled = $true, [Parameter()] - [bool] - $LoginPasswordPolicyEnforced = $true + [System.Boolean] + $LoginPasswordPolicyEnforced = $true, + + [Parameter()] + [System.Boolean] + $Disabled ) # Assume the test will pass $testPassed = $true - + $getParams = @{ - Name = $Name - SQLServer = $SQLServer - SQLInstanceName = $SQLInstanceName + Name = $Name + ServerName = $ServerName + InstanceName = $InstanceName } $loginInfo = Get-TargetResource @getParams if ( $Ensure -ne $loginInfo.Ensure ) { - New-VerboseMessage -Message "The login '$Name' on the instance '$SQLServer\$SQLInstanceName' is $($loginInfo.Ensure) rather than $Ensure" + New-VerboseMessage -Message "The login '$Name' on the instance '$ServerName\$InstanceName' is $($loginInfo.Ensure) rather than $Ensure" $testPassed = $false } @@ -353,7 +385,13 @@ function Test-TargetResource { if ( $LoginType -ne $loginInfo.LoginType ) { - New-VerboseMessage -Message "The login '$Name' on the instance '$SQLServer\$SQLInstanceName' is a $($loginInfo.LoginType) rather than $LoginType" + New-VerboseMessage -Message "The login '$Name' on the instance '$ServerName\$InstanceName' is a $($loginInfo.LoginType) rather than $LoginType" + $testPassed = $false + } + + if ( $PSBoundParameters.ContainsKey('Disabled') -and ($loginInfo.Disabled -ne $Disabled) ) + { + New-VerboseMessage -Message "The login '$Name' on the instance '$ServerName\$InstanceName' has IsDisabled set to $($loginInfo.Disabled) rather than $Disabled" $testPassed = $false } @@ -361,24 +399,24 @@ function Test-TargetResource { if ( $LoginPasswordExpirationEnabled -ne $loginInfo.LoginPasswordExpirationEnabled ) { - New-VerboseMessage -Message "The login '$Name' on the instance '$SQLServer\$SQLInstanceName' has PasswordExpirationEnabled set to $($loginInfo.LoginPasswordExpirationEnabled) rather than $LoginPasswordExpirationEnabled" + New-VerboseMessage -Message "The login '$Name' on the instance '$ServerName\$InstanceName' has PasswordExpirationEnabled set to $($loginInfo.LoginPasswordExpirationEnabled) rather than $LoginPasswordExpirationEnabled" $testPassed = $false } if ( $LoginPasswordPolicyEnforced -ne $loginInfo.LoginPasswordPolicyEnforced ) { - New-VerboseMessage -Message "The login '$Name' on the instance '$SQLServer\$SQLInstanceName' has PasswordPolicyEnforced set to $($loginInfo.LoginPasswordPolicyEnforced) rather than $LoginPasswordPolicyEnforced" + New-VerboseMessage -Message "The login '$Name' on the instance '$ServerName\$InstanceName' has PasswordPolicyEnforced set to $($loginInfo.LoginPasswordPolicyEnforced) rather than $LoginPasswordPolicyEnforced" $testPassed = $false } # If testPassed is still true and a login credential was specified, test the password if ( $testPassed -and $LoginCredential ) { - $userCred = [System.Management.Automation.PSCredential]::new($Name, $LoginCredential.Password) - + $userCredential = [System.Management.Automation.PSCredential]::new($Name, $LoginCredential.Password) + try { - $serverObject = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName -SetupCredential $userCred + Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName -SetupCredential $userCredential | Out-Null } catch { @@ -388,7 +426,7 @@ function Test-TargetResource } } } - + return $testPassed } @@ -415,7 +453,7 @@ function Update-SQLServerLogin { $originalErrorActionPreference = $ErrorActionPreference $ErrorActionPreference = 'Stop' - + $Login.Alter() } catch @@ -471,20 +509,20 @@ function New-SQLServerLogin switch ( $PSCmdlet.ParameterSetName ) { - 'SqlLogin' - { + 'SqlLogin' + { try { $originalErrorActionPreference = $ErrorActionPreference $ErrorActionPreference = 'Stop' - - $login.Create($SecureString,$LoginCreateOptions) + + $login.Create($SecureString, $LoginCreateOptions) } catch [Microsoft.SqlServer.Management.Smo.FailedOperationException] { if ( $_.Exception.InnerException.InnerException.InnerException -match 'Password validation failed' ) { - throw New-TerminatingError -ErrorType PasswordValidationFailed -FormatArgs $Name,$_.Exception.InnerException.InnerException.InnerException -ErrorCategory SecurityError + throw New-TerminatingError -ErrorType PasswordValidationFailed -FormatArgs $Name, $_.Exception.InnerException.InnerException.InnerException -ErrorCategory SecurityError } else { @@ -507,7 +545,7 @@ function New-SQLServerLogin { $originalErrorActionPreference = $ErrorActionPreference $ErrorActionPreference = 'Stop' - + $login.Create() } catch @@ -545,7 +583,7 @@ function Remove-SQLServerLogin { $originalErrorActionPreference = $ErrorActionPreference $ErrorActionPreference = 'Stop' - + $Login.Drop() } catch @@ -588,14 +626,14 @@ function Set-SQLServerLoginPassword { $originalErrorActionPreference = $ErrorActionPreference $ErrorActionPreference = 'Stop' - + $Login.ChangePassword($SecureString) } catch [Microsoft.SqlServer.Management.Smo.FailedOperationException] { if ( $_.Exception.InnerException.InnerException.InnerException -match 'Password validation failed' ) { - throw New-TerminatingError -ErrorType PasswordValidationFailed -FormatArgs $Name,$_.Exception.InnerException.InnerException.InnerException -ErrorCategory SecurityError + throw New-TerminatingError -ErrorType PasswordValidationFailed -FormatArgs $Name, $_.Exception.InnerException.InnerException.InnerException -ErrorCategory SecurityError } else { diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerLogin/MSFT_xSQLServerLogin.schema.mof b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerLogin/MSFT_SqlServerLogin.schema.mof similarity index 86% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerLogin/MSFT_xSQLServerLogin.schema.mof rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerLogin/MSFT_SqlServerLogin.schema.mof index a8866341f..f687e0963 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerLogin/MSFT_xSQLServerLogin.schema.mof +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerLogin/MSFT_SqlServerLogin.schema.mof @@ -1,15 +1,16 @@ -[ClassVersion("1.0.0.0"), FriendlyName("xSQLServerLogin")] -class MSFT_xSQLServerLogin : OMI_BaseResource +[ClassVersion("1.0.0.0"), FriendlyName("SqlServerLogin")] +class MSFT_SqlServerLogin : OMI_BaseResource { [Write, Description("The specified login is Present or Absent. Default is Present."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; [Key, Description("The name of the login.")] String Name; [Write, Description("The type of login to be created. If LoginType is 'WindowsUser' or 'WindowsGroup' then provide the name in the format DOMAIN\name. Default is WindowsUser. Unsupported login types are Certificate, AsymmetricKey, ExternalUser, and ExternalGroup."), ValueMap{"WindowsUser","WindowsGroup","SqlLogin","Certificate","AsymmetricKey","ExternalUser","ExternalGroup"}, Values{"WindowsUser","WindowsGroup","SqlLogin","Certificate","AsymmetricKey","ExternalUser","ExternalGroup"}] String LoginType; - [Key, Description("The hostname of the SQL Server to be configured.")] String SQLServer; - [Key, Description("Name of the SQL instance to be configured.")] String SQLInstanceName; + [Key, Description("The hostname of the SQL Server to be configured.")] String ServerName; + [Key, Description("Name of the SQL instance to be configured.")] String InstanceName; [Write, EmbeddedInstance("MSFT_Credential"), Description("If LoginType is 'SqlLogin' then a PSCredential is needed for the password to the login.")] String LoginCredential; [Write, Description("Specifies if the login is required to have its password change on the next login. Only applies to SQL Logins. Default is $true.")] Boolean LoginMustChangePassword; [Write, Description("Specifies if the login password is required to expire in accordance to the operating system security policy. Only applies to SQL Logins. Default is $true.")] Boolean LoginPasswordExpirationEnabled; [Write, Description("Specifies if the login password is required to conform to the password policy specified in the system security policy. Only applies to SQL Logins. Default is $true.")] Boolean LoginPasswordPolicyEnforced; + [Write, Description("Specifies if the login is disabled. Default is $false.")] Boolean Disabled; }; diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerMaxDop/MSFT_xSQLServerMaxDop.psm1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerMaxDop/MSFT_SqlServerMaxDop.psm1 similarity index 64% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerMaxDop/MSFT_xSQLServerMaxDop.psm1 rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerMaxDop/MSFT_SqlServerMaxDop.psm1 index 06a1a7ca7..78fb15965 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerMaxDop/MSFT_xSQLServerMaxDop.psm1 +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerMaxDop/MSFT_SqlServerMaxDop.psm1 @@ -1,14 +1,14 @@ Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) ` - -ChildPath 'xSQLServerHelper.psm1') ` - -Force + -ChildPath 'SqlServerDscHelper.psm1') ` + -Force <# .SYNOPSIS This function gets the max degree of parallelism server configuration option. - .PARAMETER SQLServer + .PARAMETER ServerName The host name of the SQL Server to be configured. - .PARAMETER SQLInstanceName + .PARAMETER InstanceName The name of the SQL instance to be configured. #> function Get-TargetResource @@ -20,15 +20,18 @@ function Get-TargetResource [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] - $SQLInstanceName, + $InstanceName, [Parameter()] [ValidateNotNullOrEmpty()] [System.String] - $SQLServer = $env:COMPUTERNAME + $ServerName = $env:COMPUTERNAME ) - $sqlServerObject = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName + $sqlServerObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName + + # Is this node actively hosting the SQL instance? + $isActiveNode = Test-ActiveNode -ServerObject $sqlServerObject if ($sqlServerObject) { @@ -37,9 +40,10 @@ function Get-TargetResource } $returnValue = @{ - SQLInstanceName = $SQLInstanceName - SQLServer = $SQLServer - MaxDop = $currentMaxDop + InstanceName = $InstanceName + ServerName = $ServerName + MaxDop = $currentMaxDop + IsActiveNode = $isActiveNode } $returnValue @@ -49,14 +53,14 @@ function Get-TargetResource .SYNOPSIS This function sets the max degree of parallelism server configuration option. - .PARAMETER SQLServer + .PARAMETER ServerName The host name of the SQL Server to be configured. - .PARAMETER SQLInstanceName + .PARAMETER InstanceName The name of the SQL instance to be configured. .PARAMETER Ensure - When set to 'Present' then max degree of parallelism will be set to either the value in parameter MaxDop or dynamically configured when parameter DynamicAlloc is set to $true. + When set to 'Present' then max degree of parallelism will be set to either the value in parameter MaxDop or dynamically configured when parameter DynamicAlloc is set to $true. When set to 'Absent' max degree of parallelism will be set to 0 which means no limit in number of processors used in parallel plan execution. .PARAMETER DynamicAlloc @@ -65,6 +69,10 @@ function Get-TargetResource .PARAMETER MaxDop A numeric value to limit the number of processors used in parallel plan execution. + + .PARAMETER ProcessOnlyOnActiveNode + Specifies that the resource will only determine if a change is needed if the target node is the active host of the SQL Server Instance. + Not used in Set-TargetResource. #> function Set-TargetResource { @@ -74,15 +82,15 @@ function Set-TargetResource [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] - $SQLInstanceName, + $InstanceName, [Parameter()] [ValidateNotNullOrEmpty()] [System.String] - $SQLServer = $env:COMPUTERNAME, + $ServerName = $env:COMPUTERNAME, [Parameter()] - [ValidateSet('Present','Absent')] + [ValidateSet('Present', 'Absent')] [ValidateNotNullOrEmpty()] [System.String] $Ensure = 'Present', @@ -93,10 +101,14 @@ function Set-TargetResource [Parameter()] [System.Int32] - $MaxDop + $MaxDop, + + [Parameter()] + [System.Boolean] + $ProcessOnlyOnActiveNode ) - $sqlServerObject = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName + $sqlServerObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName if ($sqlServerObject) { @@ -110,8 +122,8 @@ function Set-TargetResource if ($MaxDop) { throw New-TerminatingError -ErrorType MaxDopParamMustBeNull ` - -FormatArgs @( $SQLServer,$SQLInstanceName ) ` - -ErrorCategory InvalidArgument + -FormatArgs @( $ServerName, $InstanceName ) ` + -ErrorCategory InvalidArgument } $targetMaxDop = Get-SqlDscDynamicMaxDop -SqlServerObject $sqlServerObject @@ -122,7 +134,7 @@ function Set-TargetResource $targetMaxDop = $MaxDop } } - + 'Absent' { $targetMaxDop = 0 @@ -139,9 +151,9 @@ function Set-TargetResource catch { throw New-TerminatingError -ErrorType MaxDopSetError ` - -FormatArgs @($SQLServer,$SQLInstanceName,$targetMaxDop) ` - -ErrorCategory InvalidOperation ` - -InnerException $_.Exception + -FormatArgs @($ServerName, $InstanceName, $targetMaxDop) ` + -ErrorCategory InvalidOperation ` + -InnerException $_.Exception } } } @@ -150,14 +162,14 @@ function Set-TargetResource .SYNOPSIS This function tests the max degree of parallelism server configuration option. - .PARAMETER SQLServer + .PARAMETER ServerName The host name of the SQL Server to be configured. - .PARAMETER SQLInstanceName + .PARAMETER InstanceName The name of the SQL instance to be configured. .PARAMETER Ensure - When set to 'Present' then max degree of parallelism will be set to either the value in parameter MaxDop or dynamically configured when parameter DynamicAlloc is set to $true. + When set to 'Present' then max degree of parallelism will be set to either the value in parameter MaxDop or dynamically configured when parameter DynamicAlloc is set to $true. When set to 'Absent' max degree of parallelism will be set to 0 which means no limit in number of processors used in parallel plan execution. .PARAMETER DynamicAlloc @@ -166,6 +178,9 @@ function Set-TargetResource .PARAMETER MaxDop A numeric value to limit the number of processors used in parallel plan execution. + + .PARAMETER ProcessOnlyOnActiveNode + Specifies that the resource will only determine if a change is needed if the target node is the active host of the SQL Server Instance. #> function Test-TargetResource { @@ -176,15 +191,15 @@ function Test-TargetResource [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] - $SQLInstanceName, + $InstanceName, [Parameter()] [ValidateNotNullOrEmpty()] [System.String] - $SQLServer = $env:COMPUTERNAME, + $ServerName = $env:COMPUTERNAME, [Parameter()] - [ValidateSet('Present','Absent')] + [ValidateSet('Present', 'Absent')] [ValidateNotNullOrEmpty()] [System.String] $Ensure = 'Present', @@ -195,20 +210,35 @@ function Test-TargetResource [Parameter()] [System.Int32] - $MaxDop + $MaxDop, + + [Parameter()] + [System.Boolean] + $ProcessOnlyOnActiveNode ) Write-Verbose -Message 'Testing the max degree of parallelism server configuration option' - + $parameters = @{ - SQLInstanceName = $PSBoundParameters.SQLInstanceName - SQLServer = $PSBoundParameters.SQLServer + InstanceName = $InstanceName + ServerName = $ServerName } - - $currentValues = Get-TargetResource @parameters + + $currentValues = Get-TargetResource @parameters + $getMaxDop = $currentValues.MaxDop $isMaxDopInDesiredState = $true + <# + If this is supposed to process only the active node, and this is not the + active node, don't bother evaluating the test. + #> + if ( $ProcessOnlyOnActiveNode -and -not $getTargetResourceResult.IsActiveNode ) + { + New-VerboseMessage -Message ( 'The node "{0}" is not actively hosting the instance "{1}". Exiting the test.' -f $env:COMPUTERNAME, $InstanceName ) + return $isMaxDopInDesiredState + } + switch ($Ensure) { 'Absent' @@ -226,8 +256,8 @@ function Test-TargetResource if ($MaxDop) { throw New-TerminatingError -ErrorType MaxDopParamMustBeNull ` - -FormatArgs @( $SQLServer,$SQLInstanceName ) ` - -ErrorCategory InvalidArgument + -FormatArgs @( $ServerName, $InstanceName ) ` + -ErrorCategory InvalidArgument } $dynamicMaxDop = Get-SqlDscDynamicMaxDop @@ -239,7 +269,7 @@ function Test-TargetResource $isMaxDopInDesiredState = $false } } - else + else { if ($getMaxDop -ne $MaxDop) { @@ -250,7 +280,7 @@ function Test-TargetResource } } - $isMaxDopInDesiredState + $isMaxDopInDesiredState } <# @@ -260,20 +290,33 @@ function Test-TargetResource function Get-SqlDscDynamicMaxDop { $cimInstanceProc = Get-CimInstance -ClassName Win32_Processor - $numProcs = (Measure-Object -InputObject $cimInstanceProc -Property NumberOfLogicalProcessors -Sum).Sum - $numCores = (Measure-Object -InputObject $cimInstanceProc -Property NumberOfCores -Sum).Sum - if ($numProcs -eq 1) + # init variables + $numberOfLogicalProcessors = 0 + $numberOfCores = 0 + + # Loop through returned objects + foreach ($processor in $cimInstanceProc) + { + # increment number of processors + $numberOfLogicalProcessors += $processor.NumberOfLogicalProcessors + + # increment number of cores + $numberOfCores += $processor.NumberOfCores + } + + + if ($numberOfLogicalProcessors -eq 1) { - $dynamicMaxDop = [Math]::Round($numCores / 2, [System.MidpointRounding]::AwayFromZero) + $dynamicMaxDop = [Math]::Round($numberOfCores / 2, [System.MidpointRounding]::AwayFromZero) } - elseif ($numCores -ge 8) + elseif ($numberOfCores -ge 8) { $dynamicMaxDop = 8 } else { - $dynamicMaxDop = $numCores + $dynamicMaxDop = $numberOfCores } $dynamicMaxDop diff --git a/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerMaxDop/MSFT_SqlServerMaxDop.schema.mof b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerMaxDop/MSFT_SqlServerMaxDop.schema.mof new file mode 100644 index 000000000..95f24dba7 --- /dev/null +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerMaxDop/MSFT_SqlServerMaxDop.schema.mof @@ -0,0 +1,11 @@ +[ClassVersion("1.0.0.0"), FriendlyName("SqlServerMaxDop")] +class MSFT_SqlServerMaxDop : OMI_BaseResource +{ + [Write, Description("When set to 'Present' then max degree of parallelism will be set to either the value in parameter MaxDop or dynamically configured when parameter DynamicAlloc is set to $true. When set to 'Absent' max degree of parallelism will be set to 0 which means no limit in number of processors used in parallel plan execution."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; + [Write, Description("If set to $true then max degree of parallelism will be dynamically configured. When this is set parameter is set to $true, the parameter MaxDop must be set to $null or not be configured.")] Boolean DynamicAlloc; + [Write, Description("A numeric value to limit the number of processors used in parallel plan execution.")] SInt32 MaxDop; + [Write, Description("The host name of the SQL Server to be configured. Default value is $env:COMPUTERNAME.")] String ServerName; + [Key, Description("The name of the SQL instance to be configured.")] String InstanceName; + [Write, Description("Specifies that the resource will only determine if a change is needed if the target node is the active host of the SQL Server instance.")] Boolean ProcessOnlyOnActiveNode; + [Read, Description("Determines if the current node is actively hosting the SQL Server instance.")] Boolean IsActiveNode; +}; diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerMemory/MSFT_xSQLServerMemory.psm1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerMemory/MSFT_SqlServerMemory.psm1 similarity index 59% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerMemory/MSFT_xSQLServerMemory.psm1 rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerMemory/MSFT_SqlServerMemory.psm1 index 9814ef450..b637df416 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerMemory/MSFT_xSQLServerMemory.psm1 +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerMemory/MSFT_SqlServerMemory.psm1 @@ -1,14 +1,14 @@ -Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) -ChildPath 'xSQLServerHelper.psm1') -Force +Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) -ChildPath 'SqlServerDscHelper.psm1') -Force <# .SYNOPSIS - This function gets the value of the min and max memory server configuration option. + This function gets the value of the min and max memory server configuration option. - .PARAMETER SQLServer - The host name of the SQL Server to be configured. + .PARAMETER ServerName + The host name of the SQL Server to be configured. - .PARAMETER SQLInstanceName - The name of the SQL instance to be configured. + .PARAMETER InstanceName + The name of the SQL instance to be configured. #> function Get-TargetResource @@ -20,28 +20,32 @@ function Get-TargetResource [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] - $SQLInstanceName, + $InstanceName, [Parameter()] [ValidateNotNullOrEmpty()] [System.String] - $SQLServer = $env:COMPUTERNAME + $ServerName = $env:COMPUTERNAME ) - $sqlServerObject = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName + $sqlServerObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName if ($sqlServerObject) { Write-Verbose -Message 'Getting the value for minimum and maximum SQL server memory.' $minMemory = $sqlServerObject.Configuration.MinServerMemory.ConfigValue $maxMemory = $sqlServerObject.Configuration.MaxServerMemory.ConfigValue + + # Is this node actively hosting the SQL instance? + $isActiveNode = Test-ActiveNode -ServerObject $sqlServerObject } $returnValue = @{ - SQLInstanceName = $SQLInstanceName - SQLServer = $SQLServer - MinMemory = $minMemory - MaxMemory = $maxMemory + InstanceName = $InstanceName + ServerName = $ServerName + MinMemory = $minMemory + MaxMemory = $maxMemory + IsActiveNode = $isActiveNode } $returnValue @@ -49,27 +53,31 @@ function Get-TargetResource <# .SYNOPSIS - This function sets the value for the min and max memory server configuration option. + This function sets the value for the min and max memory server configuration option. + + .PARAMETER ServerName + The host name of the SQL Server to be configured. - .PARAMETER SQLServer - The host name of the SQL Server to be configured. + .PARAMETER InstanceName + The name of the SQL instance to be configured. - .PARAMETER SQLInstanceName - The name of the SQL instance to be configured. - .PARAMETER Ensure - When set to 'Present' then min and max memory will be set to either the value in parameter MinMemory and MaxMemory or dynamically configured when parameter DynamicAlloc is set to $true. - When set to 'Absent' min and max memory will be set to default values. + When set to 'Present' then min and max memory will be set to either the value in parameter MinMemory and MaxMemory or dynamically configured when parameter DynamicAlloc is set to $true. + When set to 'Absent' min and max memory will be set to default values. .PARAMETER DynamicAlloc - If set to $true then max memory will be dynamically configured. - When this is set parameter is set to $true, the parameter MaxMemory must be set to $null or not be configured. + If set to $true then max memory will be dynamically configured. + When this is set parameter is set to $true, the parameter MaxMemory must be set to $null or not be configured. .PARAMETER MinMemory - This is the minimum amount of memory, in MB, in the buffer pool used by the instance of SQL Server. + This is the minimum amount of memory, in MB, in the buffer pool used by the instance of SQL Server. .PARAMETER MaxMemory - This is the maximum amount of memory, in MB, in the buffer pool used by the instance of SQL Server. + This is the maximum amount of memory, in MB, in the buffer pool used by the instance of SQL Server. + + .PARAMETER ProcessOnlyOnActiveNode + Specifies that the resource will only determine if a change is needed if the target node is the active host of the SQL Server instance. + Not used in Set-TargetResource. #> function Set-TargetResource { @@ -79,15 +87,15 @@ function Set-TargetResource [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] - $SQLInstanceName, + $InstanceName, [Parameter()] [ValidateNotNullOrEmpty()] [System.String] - $SQLServer = $env:COMPUTERNAME, + $ServerName = $env:COMPUTERNAME, [Parameter()] - [ValidateSet('Present','Absent')] + [ValidateSet('Present', 'Absent')] [System.String] $Ensure = 'Present', @@ -98,14 +106,18 @@ function Set-TargetResource [Parameter()] [System.Int32] $MinMemory, - + [Parameter()] [System.Int32] - $MaxMemory + $MaxMemory, + + [Parameter()] + [System.Boolean] + $ProcessOnlyOnActiveNode ) - $sqlServerObject = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName - + $sqlServerObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName + if ($sqlServerObject) { Write-Verbose -Message 'Setting the minimum and maximum memory used by the instance.' @@ -118,8 +130,8 @@ function Set-TargetResource if ($MaxMemory) { throw New-TerminatingError -ErrorType MaxMemoryParamMustBeNull ` - -FormatArgs @( $SQLServer,$SQLInstanceName ) ` - -ErrorCategory InvalidArgument + -FormatArgs @( $ServerName, $InstanceName ) ` + -ErrorCategory InvalidArgument } $MaxMemory = Get-SqlDscDynamicMaxMemory @@ -130,21 +142,21 @@ function Set-TargetResource if (-not $MaxMemory) { throw New-TerminatingError -ErrorType MaxMemoryParamMustNotBeNull ` - -FormatArgs @( $SQLServer,$SQLInstanceName ) ` - -ErrorCategory InvalidArgument + -FormatArgs @( $ServerName, $InstanceName ) ` + -ErrorCategory InvalidArgument } } $sqlServerObject.Configuration.MaxServerMemory.ConfigValue = $MaxMemory New-VerboseMessage -Message "Maximum memory used by the instance has been limited to $($MaxMemory)MB." } - + 'Absent' { $sqlServerObject.Configuration.MaxServerMemory.ConfigValue = 2147483647 $sqlServerObject.Configuration.MinServerMemory.ConfigValue = 0 New-VerboseMessage -Message ('Ensure is set to absent. Minimum and maximum server memory' + ` - 'values used by the instance are reset to the default values.') + 'values used by the instance are reset to the default values.') } } @@ -161,36 +173,39 @@ function Set-TargetResource catch { throw New-TerminatingError -ErrorType AlterServerMemoryFailed ` - -FormatArgs @($SQLServer,$SQLInstanceName) ` - -ErrorCategory InvalidOperation ` - -InnerException $_.Exception + -FormatArgs @($ServerName, $InstanceName) ` + -ErrorCategory InvalidOperation ` + -InnerException $_.Exception } } } <# .SYNOPSIS - This function tests the value of the min and max memory server configuration option. + This function tests the value of the min and max memory server configuration option. + + .PARAMETER ServerName + The host name of the SQL Server to be configured. - .PARAMETER SQLServer - The host name of the SQL Server to be configured. + .PARAMETER InstanceName + The name of the SQL instance to be configured. - .PARAMETER SQLInstanceName - The name of the SQL instance to be configured. - .PARAMETER Ensure - When set to 'Present' then min and max memory will be set to either the value in parameter MinMemory and MaxMemory or dynamically configured when parameter DynamicAlloc is set to $true. - When set to 'Absent' min and max memory will be set to default values. + When set to 'Present' then min and max memory will be set to either the value in parameter MinMemory and MaxMemory or dynamically configured when parameter DynamicAlloc is set to $true. + When set to 'Absent' min and max memory will be set to default values. .PARAMETER DynamicAlloc - If set to $true then max memory will be dynamically configured. - When this is set parameter is set to $true, the parameter MaxMemory must be set to $null or not be configured. + If set to $true then max memory will be dynamically configured. + When this is set parameter is set to $true, the parameter MaxMemory must be set to $null or not be configured. .PARAMETER MinMemory - This is the minimum amount of memory, in MB, in the buffer pool used by the instance of SQL Server. + This is the minimum amount of memory, in MB, in the buffer pool used by the instance of SQL Server. .PARAMETER MaxMemory - This is the maximum amount of memory, in MB, in the buffer pool used by the instance of SQL Server. + This is the maximum amount of memory, in MB, in the buffer pool used by the instance of SQL Server. + + .PARAMETER ProcessOnlyOnActiveNode + Specifies that the resource will only determine if a change is needed if the target node is the active host of the SQL Server instance. #> function Test-TargetResource { @@ -201,15 +216,15 @@ function Test-TargetResource [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] - $SQLInstanceName, + $InstanceName, [Parameter()] [ValidateNotNullOrEmpty()] [System.String] - $SQLServer = $env:COMPUTERNAME, + $ServerName = $env:COMPUTERNAME, [Parameter()] - [ValidateSet("Present","Absent")] + [ValidateSet("Present", "Absent")] [System.String] $Ensure = 'Present', @@ -223,22 +238,37 @@ function Test-TargetResource [Parameter()] [System.Int32] - $MaxMemory + $MaxMemory, + + [Parameter()] + [System.Boolean] + $ProcessOnlyOnActiveNode ) - Write-Verbose -Message 'Testing the values of the minimum and maximum memory server configuration option set to be used by the instance.' + Write-Verbose -Message 'Testing the values of the minimum and maximum memory server configuration option set to be used by the instance.' $getTargetResourceParameters = @{ - SQLInstanceName = $PSBoundParameters.SQLInstanceName - SQLServer = $PSBoundParameters.SQLServer + InstanceName = $InstanceName + ServerName = $ServerName } $getTargetResourceResult = Get-TargetResource @getTargetResourceParameters - + $currentMinMemory = $getTargetResourceResult.MinMemory $currentMaxMemory = $getTargetResourceResult.MaxMemory $isServerMemoryInDesiredState = $true + <# + If this is supposed to process only the active node, and this is not the + active node, don't bother evaluating the test. + #> + if ( $ProcessOnlyOnActiveNode -and -not $getTargetResourceResult.IsActiveNode ) + { + # Use localization if the resource has been converted + New-VerboseMessage -Message ( 'The node "{0}" is not actively hosting the instance "{1}". Exiting the test.' -f $env:COMPUTERNAME, $InstanceName ) + return $isServerMemoryInDesiredState + } + switch ($Ensure) { 'Absent' @@ -263,8 +293,8 @@ function Test-TargetResource if ($MaxMemory) { throw New-TerminatingError -ErrorType MaxMemoryParamMustBeNull ` - -FormatArgs @( $SQLServer,$SQLInstanceName ) ` - -ErrorCategory InvalidArgument + -FormatArgs @( $ServerName, $InstanceName ) ` + -ErrorCategory InvalidArgument } $MaxMemory = Get-SqlDscDynamicMaxMemory @@ -275,24 +305,24 @@ function Test-TargetResource if (-not $MaxMemory) { throw New-TerminatingError -ErrorType MaxMemoryParamMustNotBeNull ` - -FormatArgs @( $SQLServer,$SQLInstanceName ) ` - -ErrorCategory InvalidArgument + -FormatArgs @( $ServerName, $InstanceName ) ` + -ErrorCategory InvalidArgument } } if ($MaxMemory -ne $currentMaxMemory) { New-VerboseMessage -Message ("Current maximum server memory used by the instance " + ` - "is $($currentMaxMemory)MB. Expected $($MaxMemory)MB.") + "is $($currentMaxMemory)MB. Expected $($MaxMemory)MB.") $isServerMemoryInDesiredState = $false } if ($MinMemory) { - if ($MinMemory -ne $currentMinMemory) + if ($MinMemory -ne $currentMinMemory) { New-VerboseMessage -Message ("Current minimum server memory used by the instance " + ` - "is $($currentMinMemory)MB. Expected $($MinMemory)MB.") + "is $($currentMinMemory)MB. Expected $($MinMemory)MB.") $isServerMemoryInDesiredState = $false } } @@ -312,7 +342,7 @@ function Get-SqlDscDynamicMaxMemory { $physicalMemory = ((Get-CimInstance -ClassName Win32_PhysicalMemory).Capacity | Measure-Object -Sum).Sum $physicalMemoryInMegaBytes = [Math]::Round($physicalMemory / 1MB) - + # Find how much to save for OS: 20% of total ram for under 15GB / 12.5% for over 20GB if ($physicalMemoryInMegaBytes -ge 20480) { @@ -335,8 +365,8 @@ function Get-SqlDscDynamicMaxMemory $numberOfSqlThreads = 0 } - $operatingSystemArchitecture = (Get-CimInstance -ClassName Win32_operatingsystem).OSArchitecture - + $operatingSystemArchitecture = (Get-CimInstance -ClassName Win32_OperatingSystem).OSArchitecture + # Find threadStackSize 1MB x86/ 2MB x64/ 4MB IA64 if ($operatingSystemArchitecture -eq '32-bit') { @@ -356,8 +386,8 @@ function Get-SqlDscDynamicMaxMemory catch { throw New-TerminatingError -ErrorType ErrorGetDynamicMaxMemory ` - -ErrorCategory InvalidOperation ` - -InnerException $_.Exception + -ErrorCategory InvalidOperation ` + -InnerException $_.Exception } $maxMemory diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerMemory/MSFT_xSQLServerMemory.schema.mof b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerMemory/MSFT_SqlServerMemory.schema.mof similarity index 58% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerMemory/MSFT_xSQLServerMemory.schema.mof rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerMemory/MSFT_SqlServerMemory.schema.mof index ef3ca5c82..462ce293c 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerMemory/MSFT_xSQLServerMemory.schema.mof +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerMemory/MSFT_SqlServerMemory.schema.mof @@ -1,10 +1,12 @@ -[ClassVersion("1.0.0.0"), FriendlyName("xSQLServerMemory")] -class MSFT_xSQLServerMemory : OMI_BaseResource +[ClassVersion("1.0.0.0"), FriendlyName("SqlServerMemory")] +class MSFT_SqlServerMemory : OMI_BaseResource { - [Key, Description("The name of the SQL instance to be configured.")] String SQLInstanceName; - [Write, Description("The host name of the SQL Server to be configured. Default value is $env:COMPUTERNAME.")] String SQLServer; + [Key, Description("The name of the SQL instance to be configured.")] String InstanceName; + [Write, Description("The host name of the SQL Server to be configured. Default value is $env:COMPUTERNAME.")] String ServerName; [Write, Description("When set to 'Present' then min and max memory will be set to either the value in parameter MinMemory and MaxMemory or dynamically configured when parameter DynamicAlloc is set to $true. When set to 'Absent' min and max memory will be set to default values. Default value is Present."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; [Write, Description("If set to $true then max memory will be dynamically configured. When this is set parameter is set to $true, the parameter MaxMemory must be set to $null or not be configured. Default value is $false.")] Boolean DynamicAlloc; - [Write, Description("Minimum amount of memory, in MB, in the buffer pool used by the instance of SQL Server.")] Sint32 MinMemory; - [Write, Description("Maximum amount of memory, in MB, in the buffer pool used by the instance of SQL Server.")] Sint32 MaxMemory; + [Write, Description("Minimum amount of memory, in MB, in the buffer pool used by the instance of SQL Server.")] SInt32 MinMemory; + [Write, Description("Maximum amount of memory, in MB, in the buffer pool used by the instance of SQL Server.")] SInt32 MaxMemory; + [Write, Description("Specifies that the resource will only determine if a change is needed if the target node is the active host of the SQL Server instance.")] Boolean ProcessOnlyOnActiveNode; + [Read, Description("Determines if the current node is actively hosting the SQL Server instance.")] Boolean IsActiveNode; }; diff --git a/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerNetwork/MSFT_SqlServerNetwork.psm1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerNetwork/MSFT_SqlServerNetwork.psm1 new file mode 100644 index 000000000..0ce468776 --- /dev/null +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerNetwork/MSFT_SqlServerNetwork.psm1 @@ -0,0 +1,383 @@ +Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) ` + -ChildPath 'SqlServerDscHelper.psm1') -Force +Import-Module -Name (Join-Path -Path (Split-Path -Path $PSScriptRoot -Parent) ` + -ChildPath 'CommonResourceHelper.psm1') + +# Load localized string data +$script:localizedData = Get-LocalizedData -ResourceName 'MSFT_SqlServerNetwork' + +<# + .SYNOPSIS + Returns the current state of the SQL Server network properties. + + .PARAMETER InstanceName + The name of the SQL instance to be configured. + + .PARAMETER ProtocolName + The name of network protocol to be configured. Only tcp is currently supported. +#> +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $InstanceName, + + # For now there is only support for the tcp protocol. + [Parameter(Mandatory = $true)] + [ValidateSet('Tcp')] + [System.String] + $ProtocolName + ) + + try + { + $applicationDomainObject = Register-SqlWmiManagement -SQLInstanceName $InstanceName + + $managedComputerObject = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer + + Write-Verbose -Message ($script:localizedData.GetNetworkProtocol -f $ProtocolName, $InstanceName) + $tcp = $managedComputerObject.ServerInstances[$InstanceName].ServerProtocols[$ProtocolName] + + Write-Verbose -Message $script:localizedData.ReadingNetworkProperties + $returnValue = @{ + InstanceName = $InstanceName + ProtocolName = $ProtocolName + IsEnabled = $tcp.IsEnabled + TcpDynamicPort = ($tcp.IPAddresses['IPAll'].IPAddressProperties['TcpDynamicPorts'].Value -ge 0) + TcpPort = $tcp.IPAddresses['IPAll'].IPAddressProperties['TcpPort'].Value + } + + $returnValue.Keys | ForEach-Object { + Write-Verbose -Message "$_ = $($returnValue[$_])" + } + } + finally + { + Unregister-SqlAssemblies -ApplicationDomain $applicationDomainObject + } + + return $returnValue +} + +<# + .SYNOPSIS + Sets the SQL Server network properties. + + .PARAMETER ServerName + The host name of the SQL Server to be configured. Default value is $env:COMPUTERNAME. + + .PARAMETER InstanceName + The name of the SQL instance to be configured. + + .PARAMETER ProtocolName + The name of network protocol to be configured. Only tcp is currently supported. + + .PARAMETER IsEnabled + Enables or disables the network protocol. + + .PARAMETER TcpDynamicPort + Specifies whether the SQL Server instance should use a dynamic port. + Value cannot be set to $true if TcpPort is set to a non-empty string. + + .PARAMETER TcpPort + The TCP port(s) that SQL Server should be listening on. + If the IP address should listen on more than one port, list all ports + separated with a comma ('1433,1500,1501'). To use this parameter set + TcpDynamicPort to 'False'. + + .PARAMETER RestartService + If set to $true then SQL Server and dependent services will be restarted + if a change to the configuration is made. The default value is $false. + + .PARAMETER RestartTimeout + Timeout value for restarting the SQL Server services. The default value + is 120 seconds. +#> +function Set-TargetResource +{ + [CmdletBinding()] + param + ( + [Parameter()] + [ValidateNotNullOrEmpty()] + [System.String] + $ServerName = $env:COMPUTERNAME, + + [Parameter(Mandatory = $true)] + [System.String] + $InstanceName, + + [Parameter(Mandatory = $true)] + [ValidateSet('Tcp')] + [System.String] + $ProtocolName, + + [Parameter()] + [System.Boolean] + $IsEnabled, + + [Parameter()] + [System.Boolean] + $TcpDynamicPort, + + [Parameter()] + [System.String] + $TcpPort, + + [Parameter()] + [System.Boolean] + $RestartService = $false, + + [Parameter()] + [System.UInt16] + $RestartTimeout = 120 + ) + + if ($TcpDynamicPort -and $TcpPort) + { + $errorMessage = $script:localizedData.ErrorDynamicAndStaticPortSpecified + New-InvalidOperationException -Message $errorMessage + } + + $getTargetResourceResult = Get-TargetResource -InstanceName $InstanceName -ProtocolName $ProtocolName + + try + { + $applicationDomainObject = Register-SqlWmiManagement -SQLInstanceName $InstanceName + + $desiredState = @{ + InstanceName = $InstanceName + ProtocolName = $ProtocolName + IsEnabled = $IsEnabled + TcpDynamicPort = $TcpDynamicPort + TcpPort = $TcpPort + } + + $isRestartNeeded = $false + + $managedComputerObject = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer + + Write-Verbose -Message ($script:localizedData.GetNetworkProtocol -f $ProtocolName, $InstanceName) + $tcp = $managedComputerObject.ServerInstances[$InstanceName].ServerProtocols[$ProtocolName] + + Write-Verbose -Message ($script:localizedData.CheckingProperty -f 'IsEnabled') + if ($desiredState.IsEnabled -ine $getTargetResourceResult.IsEnabled) + { + Write-Verbose -Message ($script:localizedData.UpdatingProperty -f 'IsEnabled', $getTargetResourceResult.IsEnabled, $desiredState.IsEnabled) + $tcp.IsEnabled = $desiredState.IsEnabled + $tcp.Alter() + + $isRestartNeeded = $true + } + + Write-Verbose -Message ($script:localizedData.CheckingProperty -f 'TcpDynamicPort') + if ($desiredState.TcpDynamicPort -ne $getTargetResourceResult.TcpDynamicPort) + { + # Translates the current and desired state to a string for display + $dynamicPortDisplayValueTable = @{ + $true = 'enabled' + $false = 'disabled' + } + + # Translates the desired state to a valid value + $desiredDynamicPortValue = @{ + $true = '0' + $false = '' + } + + $fromTcpDynamicPortDisplayValue = $dynamicPortDisplayValueTable[$getTargetResourceResult.TcpDynamicPort] + $toTcpDynamicPortDisplayValue = $dynamicPortDisplayValueTable[$desiredState.TcpDynamicPort] + + Write-Verbose -Message ($script:localizedData.UpdatingProperty -f 'TcpDynamicPorts', $fromTcpDynamicPortDisplayValue, $toTcpDynamicPortDisplayValue) + $tcp.IPAddresses['IPAll'].IPAddressProperties['TcpDynamicPorts'].Value = $desiredDynamicPortValue[$desiredState.TcpDynamicPort] + $tcp.Alter() + + $isRestartNeeded = $true + } + + Write-Verbose -Message ($script:localizedData.CheckingProperty -f 'TcpPort') + if ($desiredState.TcpPort -ine $getTargetResourceResult.TcpPort) + { + $fromTcpPort = $getTargetResourceResult.TcpPort + if ($fromTcpPort -eq '') + { + $fromTcpPort = 'none' + } + + $toTcpPort = $desiredState.TcpPort + if ($toTcpPort -eq '') + { + $toTcpPort = 'none' + } + + Write-Verbose -Message ($script:localizedData.UpdatingProperty -f 'TcpPort', $fromTcpPort, $toTcpPort) + $tcp.IPAddresses['IPAll'].IPAddressProperties['TcpPort'].Value = $desiredState.TcpPort + $tcp.Alter() + + $isRestartNeeded = $true + } + + if ($RestartService -and $isRestartNeeded) + { + Restart-SqlService -SQLServer $ServerName -SQLInstanceName $InstanceName -Timeout $RestartTimeout + } + } + finally + { + Unregister-SqlAssemblies -ApplicationDomain $applicationDomainObject + } +} + +<# + .SYNOPSIS + Sets the SQL Server network properties. + + .PARAMETER ServerName + The host name of the SQL Server to be configured. Default value is $env:COMPUTERNAME. + + Not used in Test-TargetResource. + + .PARAMETER InstanceName + The name of the SQL instance to be configured. + + .PARAMETER ProtocolName + The name of network protocol to be configured. Only tcp is currently supported. + + .PARAMETER IsEnabled + Enables or disables the network protocol. + + .PARAMETER TcpDynamicPort + Specifies whether the SQL Server instance should use a dynamic port. + Value cannot be set to $true if TcpPort is set to a non-empty string. + + .PARAMETER TcpPort + The TCP port(s) that SQL Server should be listening on. + If the IP address should listen on more than one port, list all ports + separated with a comma ('1433,1500,1501'). To use this parameter set + TcpDynamicPort to 'False'. + + .PARAMETER RestartService + If set to $true then SQL Server and dependent services will be restarted + if a change to the configuration is made. The default value is $false. + + Not used in Test-TargetResource. + + .PARAMETER RestartTimeout + Timeout value for restarting the SQL Server services. The default value + is 120 seconds. + + Not used in Test-TargetResource. +#> +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param( + [Parameter()] + [ValidateNotNullOrEmpty()] + [System.String] + $ServerName = $env:COMPUTERNAME, + + [Parameter(Mandatory = $true)] + [System.String] + $InstanceName, + + [Parameter(Mandatory = $true)] + [ValidateSet('Tcp')] + [System.String] + $ProtocolName, + + [Parameter()] + [System.Boolean] + $IsEnabled, + + [Parameter()] + [System.Boolean] + $TcpDynamicPort, + + [Parameter()] + [System.String] + $TcpPort, + + [Parameter()] + [System.Boolean] + $RestartService = $false, + + [Parameter()] + [System.UInt16] + $RestartTimeout = 120 + ) + + if ($TcpDynamicPort -and $TcpPort) + { + $errorMessage = $script:localizedData.ErrorDynamicAndStaticPortSpecified + New-InvalidOperationException -Message $errorMessage + } + + $getTargetResourceResult = Get-TargetResource -InstanceName $InstanceName -ProtocolName $ProtocolName + + Write-Verbose -Message $script:localizedData.CompareStates + + $isInDesiredState = $true + + if ($ProtocolName -ne $getTargetResourceResult.ProtocolName) + { + Write-Verbose -Message ($script:localizedData.ExpectedPropertyValue -f 'ProtocolName', $ProtocolName, $getTargetResourceResult.ProtocolName) + + $isInDesiredState = $false + } + + if ($PSBoundParameters.ContainsKey('IsEnabled')) + { + if ($IsEnabled -ne $getTargetResourceResult.IsEnabled) + { + $evaluateEnableOrDisable = @{ + $true = 'enabled' + $false = 'disabled' + } + + Write-Verbose -Message ($script:localizedData.ExpectedPropertyValue -f 'IsEnabled', $evaluateEnableOrDisable[$IsEnabled], $evaluateEnableOrDisable[$getTargetResourceResult.IsEnabled]) + + $isInDesiredState = $false + } + } + + if ($PSBoundParameters.ContainsKey('TcpDynamicPort')) + { + if ($TcpDynamicPort -and $getTargetResourceResult.TcpDynamicPort -eq $false) + { + Write-Verbose -Message ($script:localizedData.ExpectedPropertyValue -f 'TcpDynamicPort', $TcpDynamicPort, $getTargetResourceResult.TcpDynamicPort) + + $isInDesiredState = $false + } + } + + if ($PSBoundParameters.ContainsKey('TcpPort')) + { + if ($getTargetResourceResult.TcpPort -eq '') + { + Write-Verbose -Message ($script:localizedData.ExpectedPropertyValue -f 'TcpPort', $TcpPort, $getTargetResourceResult.TcpPort) + + $isInDesiredState = $false + } + elseif ($TcpPort -ne $getTargetResourceResult.TcpPort) + { + Write-Verbose -Message ($script:localizedData.ExpectedPropertyValue -f 'TcpPort', $TcpPort, $getTargetResourceResult.TcpPort) + + $isInDesiredState = $false + } + } + + if ($isInDesiredState) + { + Write-Verbose -Message ($script:localizedData.InDesiredState) + } + + return $isInDesiredState +} + +Export-ModuleMember -Function *-TargetResource diff --git a/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerNetwork/MSFT_SqlServerNetwork.schema.mof b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerNetwork/MSFT_SqlServerNetwork.schema.mof new file mode 100644 index 000000000..1ce38653c --- /dev/null +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerNetwork/MSFT_SqlServerNetwork.schema.mof @@ -0,0 +1,12 @@ +[ClassVersion("1.0.0.0"), FriendlyName("SqlServerNetwork")] +class MSFT_SqlServerNetwork : OMI_BaseResource +{ + [Key, Description("The name of the SQL instance to be configured.")] String InstanceName; + [Required, Description("The name of network protocol to be configured. Only tcp is currently supported."), ValueMap{"Tcp"}, Values{"Tcp"}] String ProtocolName; + [Write, Description("The host name of the SQL Server to be configured. Default value is $env:COMPUTERNAME.")] String ServerName; + [Write, Description("Enables or disables the network protocol.")] Boolean IsEnabled; + [Write, Description("Specifies whether the SQL Server instance should use a dynamic port. Value cannot be set to 'True' if TcpPort is set to a non-empty string.")] Boolean TcpDynamicPort; + [Write, Description("The TCP port(s) that SQL Server should be listening on. If the IP address should listen on more than one port, list all ports separated with a comma ('1433,1500,1501'). To use this parameter set TcpDynamicPorts to 'False'.")] String TcpPort; + [Write, Description("If set to $true then SQL Server and dependent services will be restarted if a change to the configuration is made. The default value is $false.")] Boolean RestartService; + [Write, Description("Timeout value for restarting the SQL Server services. The default value is 120 seconds.")] UInt16 RestartTimeout; +}; diff --git a/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerNetwork/en-US/MSFT_SqlServerNetwork.strings.psd1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerNetwork/en-US/MSFT_SqlServerNetwork.strings.psd1 new file mode 100644 index 000000000..2454c12de --- /dev/null +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerNetwork/en-US/MSFT_SqlServerNetwork.strings.psd1 @@ -0,0 +1,12 @@ +# Localized resources for SqlServerNetwork + +ConvertFrom-StringData @' + GetNetworkProtocol = Getting network protocol [{0}] for SQL instance [{1}]. + ReadingNetworkProperties = Reading current network properties. + CheckingProperty = Checking [{0}] property. + UpdatingProperty = Updating property [{0}] from [{1}] to [{2}]. + ExpectedPropertyValue = Expected property [{0}] value to be [{1}] but was [{2}]. + CompareStates = Comparing desired state with current state. + InDesiredState = System is in the desired state. + ErrorDynamicAndStaticPortSpecified = Unable to set both tcp dynamic port and tcp static port. Only one can be set. +'@ diff --git a/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerPermission/MSFT_SqlServerPermission.psm1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerPermission/MSFT_SqlServerPermission.psm1 new file mode 100644 index 000000000..86454008d --- /dev/null +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerPermission/MSFT_SqlServerPermission.psm1 @@ -0,0 +1,357 @@ +Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) ` + -ChildPath 'SqlServerDscHelper.psm1') ` + -Force +<# + .SYNOPSIS + Returns the current state of the permissions for the principal (login). + + .PARAMETER InstanceName + The name of the SQL instance to be configured. + + .PARAMETER ServerName + The host name of the SQL Server to be configured. + + .PARAMETER Principal + The login to which permission will be set. + + .PARAMETER Permission + The permission to set for the login. Valid values are AlterAnyAvailabilityGroup, ViewServerState or AlterAnyEndPoint. +#> +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $InstanceName, + + [Parameter()] + [System.String] + $ServerName = $env:COMPUTERNAME, + + [Parameter(Mandatory = $true)] + [System.String] + $Principal, + + [Parameter()] + [ValidateSet('ConnectSql', 'AlterAnyAvailabilityGroup', 'ViewServerState', 'AlterAnyEndPoint')] + [System.String[]] + $Permission + ) + + New-VerboseMessage -Message "Enumerating permissions for $Principal" + + try + { + $sqlServerObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName + + # Gets a set of permissions granted based on the desired permissions in $Permission + $desiredPermissionSet = Get-SQLServerPermissionSet -Permission $Permission + $grantedPermissionSet = $sqlServerObject.EnumServerPermissions( $Principal, $desiredPermissionSet ) | + Where-Object { $_.PermissionState -eq 'Grant' } + + if ($null -ne $grantedPermissionSet) + { + $concatenatedGrantedPermissionSet = Get-SQLServerPermissionSet -PermissionSet $grantedPermissionSet.PermissionType + + # Compare desired and granted permissions based on the permissions properties from $Permission. + if (-not (Compare-Object -ReferenceObject $desiredPermissionSet -DifferenceObject $concatenatedGrantedPermissionSet -Property $Permission)) + { + $ensure = 'Present' + } + else + { + $ensure = 'Absent' + } + + # Return granted permissions as a string array. + $grantedPermission = Get-SQLPermission -ServerPermissionSet $concatenatedGrantedPermissionSet + } + else + { + $ensure = 'Absent' + $grantedPermission = '' + } + } + catch + { + throw New-TerminatingError -ErrorType PermissionGetError -FormatArgs @($Principal) -ErrorCategory InvalidOperation -InnerException $_.Exception + } + + return @{ + InstanceName = [System.String] $InstanceName + ServerName = [System.String] $ServerName + Ensure = [System.String] $ensure + Principal = [System.String] $Principal + Permission = [System.String[]] $grantedPermission + } +} + +<# + .SYNOPSIS + Grants or revokes the permission for the the principal (login). + + .PARAMETER InstanceName + The name of the SQL instance to be configured. + + .PARAMETER ServerName + The host name of the SQL Server to be configured. + + .PARAMETER Ensure + If the permission should be present or absent. Default value is 'Present'. + + .PARAMETER Principal + The login to which permission will be set. + + .PARAMETER Permission + The permission to set for the login. Valid values are AlterAnyAvailabilityGroup, ViewServerState or AlterAnyEndPoint. +#> +function Set-TargetResource +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $InstanceName, + + [Parameter()] + [System.String] + $ServerName = $env:COMPUTERNAME, + + [Parameter()] + [ValidateSet('Present', 'Absent')] + [System.String] + $Ensure = 'Present', + + [Parameter(Mandatory = $true)] + [System.String] + $Principal, + + [Parameter()] + [ValidateSet('ConnectSql', 'AlterAnyAvailabilityGroup', 'ViewServerState', 'AlterAnyEndPoint')] + [System.String[]] + $Permission + ) + + $getTargetResourceParameters = @{ + InstanceName = [System.String] $InstanceName + ServerName = [System.String] $ServerName + Principal = [System.String] $Principal + Permission = [System.String[]] $Permission + } + + $getTargetResourceResult = Get-TargetResource @getTargetResourceParameters + + if ($getTargetResourceResult.Ensure -ne $Ensure) + { + try + { + $sqlServerObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName + + $permissionSet = Get-SQLServerPermissionSet -Permission $Permission + + if ($Ensure -eq 'Present') + { + Write-Verbose -Message ('Grant permission for ''{0}''' -f $Principal) + + $sqlServerObject.Grant($permissionSet, $Principal) + } + else + { + Write-Verbose -Message ('Revoke permission for ''{0}''' -f $Principal) + + $sqlServerObject.Revoke($permissionSet, $Principal) + } + } + catch + { + throw New-TerminatingError -ErrorType ChangingPermissionFailed -FormatArgs @($Principal) -ErrorCategory InvalidOperation -InnerException $_.Exception + } + } + else + { + New-VerboseMessage -Message "State is already $Ensure" + } +} + +<# + .SYNOPSIS + Tests if the principal (login) has the desired permissions. + + .PARAMETER InstanceName + The name of the SQL instance to be configured. + + .PARAMETER ServerName + The host name of the SQL Server to be configured. + + .PARAMETER Ensure + If the permission should be present or absent. Default value is 'Present'. + + .PARAMETER Principal + The login to which permission will be set. + + .PARAMETER Permission + The permission to set for the login. Valid values are AlterAnyAvailabilityGroup, ViewServerState or AlterAnyEndPoint. +#> +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $InstanceName, + + [Parameter()] + [System.String] + $ServerName = $env:COMPUTERNAME, + + [Parameter()] + [ValidateSet('Present', 'Absent')] + [System.String] + $Ensure = 'Present', + + [Parameter(Mandatory = $true)] + [System.String] + $Principal, + + [Parameter()] + [ValidateSet('ConnectSql', 'AlterAnyAvailabilityGroup', 'ViewServerState', 'AlterAnyEndPoint')] + [System.String[]] + $Permission + ) + + $getTargetResourceParameters = @{ + InstanceName = $InstanceName + ServerName = $ServerName + Principal = $Principal + Permission = $Permission + } + + New-VerboseMessage -Message "Verifying permissions for $Principal" + + $getTargetResourceResult = Get-TargetResource @getTargetResourceParameters + + return $getTargetResourceResult.Ensure -eq $Ensure +} + +<# + .SYNOPSIS + Takes a Microsoft.SqlServer.Management.Smo.ServerPermissionSet object which will be + enumerated and returned as a string array. + + .PARAMETER ServerPermissionSet + A PermissionSet object which should be enumerated. +#> +function Get-SQLPermission +{ + [CmdletBinding()] + [OutputType([System.String[]])] + param + ( + [Parameter(Mandatory = $true)] + [Microsoft.SqlServer.Management.Smo.ServerPermissionSet] + [ValidateNotNullOrEmpty()] + $ServerPermissionSet + ) + + [System.String[]] $permissionArray = @() + + foreach ($property in $($ServerPermissionSet | Get-Member -Type Property)) + { + if ($ServerPermissionSet.$($property.Name)) + { + $permissionArray += $property.Name + } + } + + return $permissionArray +} + +<# + .SYNOPSIS + Takes either an array of strings or an array of Microsoft.SqlServer.Management.Smo.ServerPermissionSet objects which + will be enumerated and concatenated to a single Microsoft.SqlServer.Management.Smo.ServerPermissionSet object. + + .PARAMETER Permission + An array of strings which should be concatenated to a single Microsoft.SqlServer.Management.Smo.ServerPermissionSet object. + + .PARAMETER ServerPermissionSet + An array of Microsoft.SqlServer.Management.Smo.ServerPermissionSet objects which should be concatenated to a single + Microsoft.SqlServer.Management.Smo.ServerPermissionSet object. +#> +function Get-SQLServerPermissionSet +{ + [CmdletBinding()] + [OutputType([System.Object])] + param + ( + [Parameter(Mandatory = $true, ParameterSetName = 'Permission')] + [System.String[]] + [ValidateNotNullOrEmpty()] + $Permission, + + [Parameter(Mandatory = $true, ParameterSetName = 'ServerPermissionSet')] + [Microsoft.SqlServer.Management.Smo.ServerPermissionSet[]] + [ValidateNotNullOrEmpty()] + $PermissionSet + ) + + if ($Permission) + { + [Microsoft.SqlServer.Management.Smo.ServerPermissionSet] $concatenatedPermissionSet = New-Object -TypeName Microsoft.SqlServer.Management.Smo.ServerPermissionSet + + foreach ($currentPermission in $Permission) + { + $concatenatedPermissionSet.$($currentPermission) = $true + } + } + else + { + $concatenatedPermissionSet = Merge-SQLPermissionSet -Object $PermissionSet + } + + return $concatenatedPermissionSet +} + +<# + .SYNOPSIS + Merges an array of any PermissionSet objects into a single PermissionSet. + + The though with this helper function si it can be used for any permission set object + because all inherits from Microsoft.SqlServer.Management.Smo.PermissionSetBase. + + .PARAMETER Object + An array of strings which should be concatenated to a single PermissionSet object. +#> +function Merge-SQLPermissionSet +{ + param + ( + [Parameter(Mandatory = $true)] + [Object[]] + [ValidateNotNullOrEmpty()] + $Object + ) + + $baseObject = New-Object -TypeName ($Object[0].GetType()) + + foreach ($currentObject in $Object) + { + foreach ($Property in $($currentObject | Get-Member -Type Property)) + { + if ($currentObject.$($Property.Name)) + { + $baseObject.$($Property.Name) = $currentObject.$($Property.Name) + } + } + } + + return $baseObject +} + +Export-ModuleMember -Function *-TargetResource diff --git a/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerPermission/MSFT_SqlServerPermission.schema.mof b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerPermission/MSFT_SqlServerPermission.schema.mof new file mode 100644 index 000000000..169c7c14f --- /dev/null +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerPermission/MSFT_SqlServerPermission.schema.mof @@ -0,0 +1,9 @@ +[ClassVersion("1.0.0.0"), FriendlyName("SqlServerPermission")] +class MSFT_SqlServerPermission : OMI_BaseResource +{ + [Key, Description("The name of the SQL instance to be configured.")] String InstanceName; + [Write, Description("The host name of the SQL Server to be configured. Default value is $env:COMPUTERNAME.")] String ServerName; + [Write, Description("If the permission should be present or absent. Default value is 'Present'."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; + [Key, Description("The login to which permission will be set.")] String Principal; + [Write, Description("The permission to set for the login. Valid values are ConnectSql, AlterAnyAvailabilityGroup, ViewServerState or AlterAnyEndPoint."), ValueMap{"ConnectSql","AlterAnyAvailabilityGroup","ViewServerState","AlterAnyEndPoint"}, Values{"ConnectSql","AlterAnyAvailabilityGroup","ViewServerState","AlterAnyEndPoint"}] String Permission[]; +}; diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerReplication/MSFT_xSQLServerReplication.psm1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerReplication/MSFT_SqlServerReplication.psm1 similarity index 78% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerReplication/MSFT_xSQLServerReplication.psm1 rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerReplication/MSFT_SqlServerReplication.psm1 index 252d651b8..a4be6d8a9 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerReplication/MSFT_xSQLServerReplication.psm1 +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerReplication/MSFT_SqlServerReplication.psm1 @@ -1,40 +1,45 @@ -$dom = [AppDomain]::CreateDomain('xSQLServerReplication') +$dom = [AppDomain]::CreateDomain('SqlServerReplication') function Get-TargetResource { [CmdletBinding()] [OutputType([System.Collections.Hashtable])] param( - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.String] $InstanceName, + [Parameter()] [ValidateSet('Present', 'Absent')] [System.String] $Ensure = 'Present', - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [ValidateSet('Local', 'Remote')] [System.String] $DistributorMode, - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.Management.Automation.PSCredential] $AdminLinkCredentials, + [Parameter()] [System.String] $DistributionDBName = 'distribution', + [Parameter()] [System.String] $RemoteDistributor, - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.String] $WorkingDirectory, + [Parameter()] [System.Boolean] $UseTrustedConnection = $true, + [Parameter()] [System.Boolean] $UninstallWithForce = $true ) @@ -47,33 +52,33 @@ function Get-TargetResource $localServerConnection = New-ServerConnection -SqlMajorVersion $sqlMajorVersion -SqlServerName $localSqlName $localReplicationServer = New-ReplicationServer -SqlMajorVersion $sqlMajorVersion -ServerConnection $localServerConnection - if($localReplicationServer.IsDistributor -eq $true) + if ($localReplicationServer.IsDistributor -eq $true) { $Ensure = 'Present' $DistributorMode = 'Local' } - elseif($localReplicationServer.IsPublisher -eq $true) + elseif ($localReplicationServer.IsPublisher -eq $true) { $Ensure = 'Present' $DistributorMode = 'Remote' } - if($Ensure -eq 'Present') + if ($Ensure -eq 'Present') { $DistributionDBName = $localReplicationServer.DistributionDatabase $RemoteDistributor = $localReplicationServer.DistributionServer $WorkingDirectory = $localReplicationServer.WorkingDirectory } - + $returnValue = @{ - InstanceName = $InstanceName - Ensure = $Ensure - DistributorMode = $DistributorMode + InstanceName = $InstanceName + Ensure = $Ensure + DistributorMode = $DistributorMode DistributionDBName = $DistributionDBName - RemoteDistributor = $RemoteDistributor - WorkingDirectory = $WorkingDirectory + RemoteDistributor = $RemoteDistributor + WorkingDirectory = $WorkingDirectory } - + return $returnValue } @@ -81,41 +86,46 @@ function Set-TargetResource { [CmdletBinding()] param( - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.String] $InstanceName, + [Parameter()] [ValidateSet('Present', 'Absent')] [System.String] $Ensure = 'Present', - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [ValidateSet('Local', 'Remote')] [System.String] $DistributorMode, - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.Management.Automation.PSCredential] $AdminLinkCredentials, + [Parameter()] [System.String] $DistributionDBName = 'distribution', + [Parameter()] [System.String] $RemoteDistributor, - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.String] $WorkingDirectory, + [Parameter()] [System.Boolean] $UseTrustedConnection = $true, + [Parameter()] [System.Boolean] $UninstallWithForce = $true ) - if(($DistributorMode -eq 'Remote') -and (-not $RemoteDistributor)) + if (($DistributorMode -eq 'Remote') -and (-not $RemoteDistributor)) { throw "RemoteDistributor parameter cannot be empty when DistributorMode = 'Remote'!" } @@ -126,9 +136,9 @@ function Set-TargetResource $localServerConnection = New-ServerConnection -SqlMajorVersion $sqlMajorVersion -SqlServerName $localSqlName $localReplicationServer = New-ReplicationServer -SqlMajorVersion $sqlMajorVersion -ServerConnection $localServerConnection - if($Ensure -eq 'Present') + if ($Ensure -eq 'Present') { - if($DistributorMode -eq 'Local' -and $localReplicationServer.IsDistributor -eq $false) + if ($DistributorMode -eq 'Local' -and $localReplicationServer.IsDistributor -eq $false) { Write-Verbose "Local distribution will be configured ..." @@ -150,8 +160,8 @@ function Set-TargetResource -WorkingDirectory $WorkingDirectory ` -UseTrustedConnection $UseTrustedConnection } - - if($DistributorMode -eq 'Remote' -and $localReplicationServer.IsPublisher -eq $false) + + if ($DistributorMode -eq 'Remote' -and $localReplicationServer.IsPublisher -eq $false) { Write-Verbose "Remote distribution will be configured ..." @@ -173,7 +183,7 @@ function Set-TargetResource } else #'Absent' { - if($localReplicationServer.IsDistributor -eq $true -or $localReplicationServer.IsPublisher -eq $true) + if ($localReplicationServer.IsDistributor -eq $true -or $localReplicationServer.IsPublisher -eq $true) { Write-Verbose "Distribution will be removed ..." Uninstall-Distributor -ReplicationServer $localReplicationServer -UninstallWithForce $UninstallWithForce @@ -190,36 +200,41 @@ function Test-TargetResource [CmdletBinding()] [OutputType([System.Boolean])] param( - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.String] $InstanceName, + [Parameter()] [ValidateSet('Present', 'Absent')] [System.String] $Ensure = 'Present', - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [ValidateSet('Local', 'Remote')] [System.String] $DistributorMode, - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.Management.Automation.PSCredential] $AdminLinkCredentials, + [Parameter()] [System.String] $DistributionDBName = 'distribution', + [Parameter()] [System.String] $RemoteDistributor, - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.String] $WorkingDirectory, + [Parameter()] [System.Boolean] $UseTrustedConnection = $true, + [Parameter()] [System.Boolean] $UninstallWithForce = $true ) @@ -227,15 +242,15 @@ function Test-TargetResource $result = $false $state = Get-TargetResource @PSBoundParameters - if($Ensure -eq 'Absent' -and $state.Ensure -eq 'Absent') + if ($Ensure -eq 'Absent' -and $state.Ensure -eq 'Absent') { $result = $true } - elseif($Ensure -eq 'Present' -and $state.Ensure -eq 'Present' -and $state.DistributorMode -eq $DistributorMode) + elseif ($Ensure -eq 'Present' -and $state.Ensure -eq 'Present' -and $state.DistributorMode -eq $DistributorMode) { $result = $true } - + return $result } @@ -245,11 +260,11 @@ function New-ServerConnection [CmdletBinding()] [OutputType([System.Object])] param( - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.String] $SqlMajorVersion, - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.String] $SqlServerName ) @@ -265,11 +280,11 @@ function New-ReplicationServer [CmdletBinding()] [OutputType([System.Object])] param( - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.String] $SqlMajorVersion, - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.Object] $ServerConnection ) @@ -285,15 +300,15 @@ function New-DistributionDatabase [CmdletBinding()] [OutputType([System.Object])] param( - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.String] $SqlMajorVersion, - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.String] $DistributionDBName, - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.Object] $ServerConnection ) @@ -310,19 +325,19 @@ function New-DistributionPublisher [CmdletBinding()] [OutputType([System.Object])] param( - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.String] $SqlMajorVersion, - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.String] $PublisherName, - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.Object] $ServerConnection ) - + $rmo = Get-RmoAssembly -SqlMajorVersion $SqlMajorVersion $distributorPublisher = New-object $rmo.GetType('Microsoft.SqlServer.Replication.DistributionPublisher') $PublisherName, $ServerConnection @@ -333,15 +348,15 @@ function Install-RemoteDistributor { [CmdletBinding()] param( - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.Object] $ReplicationServer, - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.String] $RemoteDistributor, - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.Management.Automation.PSCredential] $AdminLinkCredentials ) @@ -354,20 +369,20 @@ function Install-LocalDistributor { [CmdletBinding()] param( - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.Object] $ReplicationServer, - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.Management.Automation.PSCredential] $AdminLinkCredentials, - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.Object] $DistributionDB ) - Write-Verbose "Calling InstallDistributor with DistributionDB" + Write-Verbose "Calling method InstallDistributor() with DistributionDB" $ReplicationServer.InstallDistributor($AdminLinkCredentials.Password, $DistributionDB) } @@ -375,15 +390,15 @@ function Uninstall-Distributor { [CmdletBinding()] param( - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.Object] $ReplicationServer, - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.Boolean] $UninstallWithForce ) - Write-Verbose 'Calling UnistallDistributor method on ReplicationServer object' + Write-Verbose 'Calling method UninstallDistributor() on ReplicationServer object' $ReplicationServer.UninstallDistributor($UninstallWithForce) } @@ -391,27 +406,27 @@ function Register-DistributorPublisher { [CmdletBinding()] param( - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.String] $SqlMajorVersion, - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.String] $PublisherName, - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.Object] $ServerConnection, - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.String] $DistributionDBName, - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.String] $WorkingDirectory, - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.Boolean] $UseTrustedConnection ) @@ -422,7 +437,7 @@ function Register-DistributorPublisher -SqlMajorVersion $SqlMajorVersion ` -PublisherName $PublisherName ` -ServerConnection $ServerConnection - + $distributorPublisher.DistributionDatabase = $DistributionDBName $distributorPublisher.WorkingDirectory = $WorkingDirectory $distributorPublisher.PublisherSecurity.WindowsAuthentication = $UseTrustedConnection @@ -432,9 +447,9 @@ function Register-DistributorPublisher function Get-ConnectionInfoAssembly { [CmdletBinding()] - [OutputType([System.Object])] + [OutputType([System.Reflection.Assembly])] param( - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.String] $SqlMajorVersion ) @@ -448,9 +463,9 @@ function Get-ConnectionInfoAssembly function Get-RmoAssembly { [CmdletBinding()] - [OutputType([System.Object])] + [OutputType([System.Reflection.Assembly])] param( - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.String] $SqlMajorVersion ) @@ -466,7 +481,7 @@ function Get-SqlServerMajorVersion [CmdletBinding()] [OutputType([System.String])] param( - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.String] $InstanceName ) @@ -486,12 +501,12 @@ function Get-SqlLocalServerName [CmdletBinding()] [OutputType([System.String])] param( - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.String] $InstanceName ) - if($InstanceName -eq "MSSQLSERVER") + if ($InstanceName -eq "MSSQLSERVER") { return $env:COMPUTERNAME } diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerReplication/MSFT_xSQLServerReplication.schema.mof b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerReplication/MSFT_SqlServerReplication.schema.mof similarity index 88% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerReplication/MSFT_xSQLServerReplication.schema.mof rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerReplication/MSFT_SqlServerReplication.schema.mof index 609bc1aaf..1e4332e8d 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerReplication/MSFT_xSQLServerReplication.schema.mof +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerReplication/MSFT_SqlServerReplication.schema.mof @@ -1,5 +1,5 @@ -[ClassVersion("1.0.0.0"), FriendlyName("xSQLServerReplication")] -class MSFT_xSQLServerReplication : OMI_BaseResource +[ClassVersion("1.0.0.0"), FriendlyName("SqlServerReplication")] +class MSFT_SqlServerReplication : OMI_BaseResource { [Key, Description("SQL Server instance name where replication distribution will be configured")] String InstanceName; [Write, ValueMap{"Present", "Absent"}, Values{"Present", "Absent"}] String Ensure; diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerRole/MSFT_xSQLServerRole.psm1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerRole/MSFT_SqlServerRole.psm1 similarity index 61% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerRole/MSFT_xSQLServerRole.psm1 rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerRole/MSFT_SqlServerRole.psm1 index f618c6590..5ec21c9d0 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerRole/MSFT_xSQLServerRole.psm1 +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerRole/MSFT_SqlServerRole.psm1 @@ -1,13 +1,18 @@ -Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) ` - -ChildPath 'xSQLServerHelper.psm1') ` - -Force +Import-Module -Name (Join-Path -Path (Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent) ` + -ChildPath 'SqlServerDscHelper.psm1') + +Import-Module -Name (Join-Path -Path (Split-Path -Path $PSScriptRoot -Parent) ` + -ChildPath 'CommonResourceHelper.psm1') + +$script:localizedData = Get-LocalizedData -ResourceName 'MSFT_SqlServerRole' + <# .SYNOPSIS This function gets the sql server role properties. - + .PARAMETER Members The members the server role should have. - + .PARAMETER MembersToInclude The members the server role should include. @@ -17,10 +22,10 @@ Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Pare .PARAMETER ServerRoleName The name of server role to be created or dropped. - .PARAMETER SQLServer + .PARAMETER ServerName The host name of the SQL Server to be configured. - .PARAMETER SQLInstanceName + .PARAMETER InstanceName The name of the SQL instance to be configured. #> function Get-TargetResource @@ -34,7 +39,7 @@ function Get-TargetResource $Members, [Parameter()] - [System.String[]] + [System.String[]] $MembersToInclude, [Parameter()] @@ -49,46 +54,53 @@ function Get-TargetResource [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] - $SQLServer, + $ServerName, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] - $SQLInstanceName + $InstanceName ) - $sqlServerObject = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName + $sqlServerObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName $ensure = 'Present' if ($sqlServerObject) { - Write-Verbose -Message "Getting properties of SQL Server role '$ServerRoleName'." + Write-Verbose -Message ( + $script:localizedData.GetProperties ` + -f $ServerRoleName + ) + if ($sqlServerRoleObject = $sqlServerObject.Roles[$ServerRoleName]) { try { - $membersInRole = $sqlServerRoleObject.EnumMemberNames() + [System.String[]] $membersInRole = $sqlServerRoleObject.EnumMemberNames() } catch { - throw New-TerminatingError -ErrorType EnumMemberNamesServerRoleGetError ` - -FormatArgs @($SQLServer,$SQLInstanceName,$ServerRoleName) ` - -ErrorCategory InvalidOperation ` - -InnerException $_.Exception + $errorMessage = $script:localizedData.EnumMemberNamesServerRoleGetError ` + -f $ServerName, $InstanceName, $ServerRoleName + + New-InvalidOperationException -Message $errorMessage -ErrorRecord $_ } if ($Members) { if ($MembersToInclude -or $MembersToExclude) { - throw New-TerminatingError -ErrorType MembersToIncludeAndExcludeParamMustBeNull ` - -FormatArgs @($SQLServer,$SQLInstanceName) ` - -ErrorCategory InvalidArgument + $errorMessage = $script:localizedData.MembersToIncludeAndExcludeParamMustBeNull + New-InvalidOperationException -Message $errorMessage } if ( $null -ne (Compare-Object -ReferenceObject $membersInRole -DifferenceObject $Members)) { - New-VerboseMessage -Message "The desired members are not present in server role $ServerRoleName" + Write-Verbose -Message ( + $script:localizedData.DesiredMemberNotPresent ` + -f $ServerRoleName + ) + $ensure = 'Absent' } } @@ -100,7 +112,11 @@ function Get-TargetResource { if ( -not ($membersInRole.Contains($memberToInclude))) { - New-VerboseMessage -Message "The included members are not present in server role $ServerRoleName" + Write-Verbose -Message ( + $script:localizedData.MemberNotPresent ` + -f $ServerRoleName, $memberToInclude + ) + $ensure = 'Absent' } } @@ -112,7 +128,11 @@ function Get-TargetResource { if ($membersInRole.Contains($memberToExclude)) { - New-VerboseMessage -Message "The excluded members are present in server role $ServerRoleName" + Write-Verbose -Message ( + $script:localizedData.MemberPresent ` + -f $ServerRoleName, $memberToExclude + ) + $ensure = 'Absent' } } @@ -126,13 +146,13 @@ function Get-TargetResource } $returnValue = @{ - Ensure = $ensure - Members = $membersInRole - MembersToInclude = $MembersToInclude - MembersToExclude = $MembersToExclude - ServerRoleName = $ServerRoleName - SQLServer = $SQLServer - SQLInstanceName = $SQLInstanceName + Ensure = $ensure + Members = $membersInRole + MembersToInclude = $MembersToInclude + MembersToExclude = $MembersToExclude + ServerRoleName = $ServerRoleName + ServerName = $ServerName + InstanceName = $InstanceName } $returnValue } @@ -147,7 +167,7 @@ function Get-TargetResource .PARAMETER Members The members the server role should have. - + .PARAMETER MembersToInclude The members the server role should include. @@ -157,10 +177,10 @@ function Get-TargetResource .PARAMETER ServerRoleName The name of server role to be created or dropped. - .PARAMETER SQLServer + .PARAMETER ServerName The host name of the SQL Server to be configured. - .PARAMETER SQLInstanceName + .PARAMETER InstanceName The name of the SQL instance to be configured. #> function Set-TargetResource @@ -169,7 +189,7 @@ function Set-TargetResource param ( [Parameter()] - [ValidateSet('Present','Absent')] + [ValidateSet('Present', 'Absent')] [System.String] $Ensure = 'Present', @@ -178,7 +198,7 @@ function Set-TargetResource $Members, [Parameter()] - [System.String[]] + [System.String[]] $MembersToInclude, [Parameter()] @@ -193,64 +213,73 @@ function Set-TargetResource [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] - $SQLServer, + $ServerName, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] - $SQLInstanceName + $InstanceName ) - $sqlServerObject = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName + $sqlServerObject = Connect-SQL -SQLServer $ServerName -SQLInstanceName $InstanceName if ($sqlServerObject) { - Write-Verbose -Message "Setting properties of SQL Server role '$ServerRoleName'." - + Write-Verbose -Message ( + $script:localizedData.SetProperties ` + -f $ServerRoleName + ) + switch ($Ensure) { 'Absent' { - try + try { $sqlServerRoleObjectToDrop = $sqlServerObject.Roles[$ServerRoleName] if ($sqlServerRoleObjectToDrop) { - Write-Verbose -Message "Trying to drop the SQL Server role '$ServerRoleName'." + Write-Verbose -Message ( + $script:localizedData.DropRole ` + -f $ServerRoleName + ) + $sqlServerRoleObjectToDrop.Drop() - New-VerboseMessage -Message "Dropped the SQL Server role '$ServerRoleName'." } } catch { - throw New-TerminatingError -ErrorType DropServerRoleSetError ` - -FormatArgs @($SQLServer,$SQLInstanceName,$ServerRoleName) ` - -ErrorCategory InvalidOperation ` - -InnerException $_.Exception + $errorMessage = $script:localizedData.DropServerRoleSetError ` + -f $ServerName, $InstanceName, $ServerRoleName + + New-InvalidOperationException -Message $errorMessage -ErrorRecord $_ } } - + 'Present' - { + { if ($null -eq $sqlServerObject.Roles[$ServerRoleName]) { try { $sqlServerRoleObjectToCreate = New-Object -TypeName Microsoft.SqlServer.Management.Smo.ServerRole ` - -ArgumentList $sqlServerObject,$ServerRoleName + -ArgumentList $sqlServerObject, $ServerRoleName if ($sqlServerRoleObjectToCreate) { - Write-Verbose -Message "Creating the SQL Server role '$ServerRoleName'." + Write-Verbose -Message ( + $script:localizedData.CreateRole ` + -f $ServerRoleName + ) + $sqlServerRoleObjectToCreate.Create() - New-VerboseMessage -Message "Created the SQL Server role '$ServerRoleName'." } } catch { - throw New-TerminatingError -ErrorType CreateServerRoleSetError ` - -FormatArgs @($SQLServer,$SQLInstanceName,$ServerRoleName) ` - -ErrorCategory InvalidOperation ` - -InnerException $_.Exception + $errorMessage = $script:localizedData.CreateServerRoleSetError ` + -f $ServerName, $InstanceName, $ServerRoleName + + New-InvalidOperationException -Message $errorMessage -ErrorRecord $_ } } @@ -258,9 +287,8 @@ function Set-TargetResource { if ($MembersToInclude -or $MembersToExclude) { - throw New-TerminatingError -ErrorType MembersToIncludeAndExcludeParamMustBeNull ` - -FormatArgs @($SQLServer,$SQLInstanceName) ` - -ErrorCategory InvalidArgument + $errorMessage = $script:localizedData.MembersToIncludeAndExcludeParamMustBeNull + New-InvalidOperationException -Message $errorMessage } $memberNamesInRoleObject = $sqlServerObject.Roles[$ServerRoleName].EnumMemberNames() @@ -270,8 +298,8 @@ function Set-TargetResource if ( -not ($Members.Contains($memberName))) { Remove-SqlDscServerRoleMember -SqlServerObject $sqlServerObject ` - -LoginName $memberName ` - -ServerRoleName $ServerRoleName + -LoginName $memberName ` + -ServerRoleName $ServerRoleName } } @@ -280,24 +308,24 @@ function Set-TargetResource if ( -not ($memberNamesInRoleObject.Contains($memberToAdd))) { Add-SqlDscServerRoleMember -SqlServerObject $sqlServerObject ` - -LoginName $memberToAdd ` - -ServerRoleName $ServerRoleName + -LoginName $memberToAdd ` + -ServerRoleName $ServerRoleName } } } else - { + { if ($MembersToInclude) { $memberNamesInRoleObject = $sqlServerObject.Roles[$ServerRoleName].EnumMemberNames() foreach ($memberToInclude in $MembersToInclude) { - if ( -not ($memberNamesInRoleObject.Contains($memberToInclude))) + if ( -not ($memberNamesInRoleObject.Contains($memberToInclude))) { Add-SqlDscServerRoleMember -SqlServerObject $sqlServerObject ` - -LoginName $memberToInclude ` - -ServerRoleName $ServerRoleName + -LoginName $memberToInclude ` + -ServerRoleName $ServerRoleName } } } @@ -311,8 +339,8 @@ function Set-TargetResource if ($memberNamesInRoleObject.Contains($memberToExclude)) { Remove-SqlDscServerRoleMember -SqlServerObject $sqlServerObject ` - -LoginName $memberToExclude ` - -ServerRoleName $ServerRoleName + -LoginName $memberToExclude ` + -ServerRoleName $ServerRoleName } } } @@ -332,7 +360,7 @@ function Set-TargetResource .PARAMETER Members The members the server role should have. - + .PARAMETER MembersToInclude The members the server role should include. @@ -342,10 +370,10 @@ function Set-TargetResource .PARAMETER ServerRoleName The name of server role to be created or dropped. - .PARAMETER SQLServer + .PARAMETER ServerName The host name of the SQL Server to be configured. - .PARAMETER SQLInstanceName + .PARAMETER InstanceName The name of the SQL instance to be configured. #> function Test-TargetResource @@ -355,7 +383,7 @@ function Test-TargetResource param ( [Parameter()] - [ValidateSet('Present','Absent')] + [ValidateSet('Present', 'Absent')] [System.String] $Ensure = 'Present', @@ -364,7 +392,7 @@ function Test-TargetResource $Members, [Parameter()] - [System.String[]] + [System.String[]] $MembersToInclude, [Parameter()] @@ -379,45 +407,55 @@ function Test-TargetResource [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] - $SQLServer, + $ServerName, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] [System.String] - $SQLInstanceName + $InstanceName + ) + + Write-Verbose -Message ( + $script:localizedData.TestProperties ` + -f $ServerRoleName ) - Write-Verbose -Message "Testing SQL Server role $ServerRoleName properties." - $getTargetResourceParameters = @{ - SQLInstanceName = $PSBoundParameters.SQLInstanceName - SQLServer = $PSBoundParameters.SQLServer - ServerRoleName = $PSBoundParameters.ServerRoleName - Members = $PSBoundParameters.Members - MembersToInclude = $PSBoundParameters.MembersToInclude - MembersToExclude = $PSBoundParameters.MembersToExclude + InstanceName = $PSBoundParameters.InstanceName + ServerName = $PSBoundParameters.ServerName + ServerRoleName = $PSBoundParameters.ServerRoleName + Members = $PSBoundParameters.Members + MembersToInclude = $PSBoundParameters.MembersToInclude + MembersToExclude = $PSBoundParameters.MembersToExclude } - $getTargetResourceResult = Get-TargetResource @getTargetResourceParameters + $getTargetResourceResult = Get-TargetResource @getTargetResourceParameters $isServerRoleInDesiredState = $true - + switch ($Ensure) { 'Absent' { if ($getTargetResourceResult.Ensure -ne 'Absent') { - New-VerboseMessage -Message "Ensure is set to Absent. The existing role $ServerRoleName should be dropped" + Write-Verbose -Message ( + $script:localizedData.EnsureIsAbsent ` + -f $ServerRoleName + ) + $isServerRoleInDesiredState = $false } } - + 'Present' { if ($getTargetResourceResult.Ensure -ne 'Present') { - New-VerboseMessage -Message ("Ensure is set to Present. The missing role $ServerRoleName " + ` - "should be added or members are not correctly configured") + Write-Verbose -Message ( + $script:localizedData.EnsureIsPresent ` + -f $ServerRoleName + ) + $isServerRoleInDesiredState = $false } } @@ -462,23 +500,27 @@ function Add-SqlDscServerRoleMember if ( -not ($SqlServerObject.Logins[$LoginName]) ) { - throw New-TerminatingError -ErrorType LoginNotFound ` - -FormatArgs @($LoginName, $SQLServer, $SQLInstanceName) ` - -ErrorCategory ObjectNotFound + $errorMessage = $script:localizedData.LoginNotFound ` + -f $LoginName, $ServerName, $InstanceName + + New-ObjectNotFoundException -Message $errorMessage } try { - Write-Verbose -Message "Adding SQL login $LoginName in role $ServerRoleName" + Write-Verbose -Message ( + $script:localizedData.AddMemberToRole ` + -f $LoginName, $ServerRoleName + ) + $SqlServerObject.Roles[$ServerRoleName].AddMember($LoginName) - New-VerboseMessage -Message "SQL Role $ServerRoleName for $LoginName, successfullly added" } catch { - throw New-TerminatingError -ErrorType AddMemberServerRoleSetError ` - -FormatArgs @($SQLServer,$SQLInstanceName,$ServerRoleName,$LoginName) ` - -ErrorCategory InvalidOperation ` - -InnerException $_.Exception + $errorMessage = $script:localizedData.AddMemberServerRoleSetError ` + -f $ServerName, $InstanceName, $ServerRoleName, $LoginName + + New-InvalidOperationException -Message $errorMessage -ErrorRecord $_ } } @@ -518,23 +560,27 @@ function Remove-SqlDscServerRoleMember if ( -not ($SqlServerObject.Logins[$LoginName]) ) { - throw New-TerminatingError -ErrorType LoginNotFound ` - -FormatArgs @($LoginName, $SQLServer, $SQLInstanceName) ` - -ErrorCategory ObjectNotFound + $errorMessage = $script:localizedData.LoginNotFound ` + -f $LoginName, $ServerName, $InstanceName + + New-ObjectNotFoundException -Message $errorMessage } try { - Write-Verbose -Message "Removing SQL login $LoginName from role $ServerRoleName" + Write-Verbose -Message ( + $script:localizedData.RemoveMemberFromRole ` + -f $LoginName, $ServerRoleName + ) + $SqlServerObject.Roles[$ServerRoleName].DropMember($LoginName) - New-VerboseMessage -Message "SQL Role $ServerRoleName for $LoginName, successfullly dropped" } catch { - throw New-TerminatingError -ErrorType DropMemberServerRoleSetError ` - -FormatArgs @($SQLServer,$SQLInstanceName,$ServerRoleName,$LoginName) ` - -ErrorCategory InvalidOperation ` - -InnerException $_.Exception + $errorMessage = $script:localizedData.DropMemberServerRoleSetError ` + -f $ServerName, $InstanceName, $ServerRoleName, $LoginName + + New-InvalidOperationException -Message $errorMessage -ErrorRecord $_ } } diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerRole/MSFT_xSQLServerRole.schema.mof b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerRole/MSFT_SqlServerRole.schema.mof similarity index 86% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerRole/MSFT_xSQLServerRole.schema.mof rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerRole/MSFT_SqlServerRole.schema.mof index d7c1a397b..4ed3b2286 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerRole/MSFT_xSQLServerRole.schema.mof +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerRole/MSFT_SqlServerRole.schema.mof @@ -1,9 +1,9 @@ -[ClassVersion("1.0.0.0"), FriendlyName("xSQLServerRole")] -class MSFT_xSQLServerRole : OMI_BaseResource +[ClassVersion("1.0.0.0"), FriendlyName("SqlServerRole")] +class MSFT_SqlServerRole : OMI_BaseResource { [Key, Description("The name of of SQL role to add or remove.")] String ServerRoleName; - [Key, Description("The host name of the SQL Server to be configured.")] String SQLServer; - [Key, Description("The name of the SQL instance to be configured.")] String SQLInstanceName; + [Key, Description("The host name of the SQL Server to be configured.")] String ServerName; + [Key, Description("The name of the SQL instance to be configured.")] String InstanceName; [Write, Description("An enumerated value that describes if the server role is added (Present) or dropped (Absent). Default value is 'Present'."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; [Write, Description("The members the server role should have. This parameter will replace all the current server role members with the specified members.")] String Members[]; [Write, Description("The members the server role should include. This parameter will only add members to a server role. Can not be used at the same time as parameter Members.")] String MembersToInclude[]; diff --git a/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerRole/en-US/MSFT_SqlServerRole.strings.psd1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerRole/en-US/MSFT_SqlServerRole.strings.psd1 new file mode 100644 index 000000000..f1d304e22 --- /dev/null +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServerRole/en-US/MSFT_SqlServerRole.strings.psd1 @@ -0,0 +1,23 @@ +# Localized resources for SqlServerRole + +ConvertFrom-StringData @' + GetProperties = Getting properties of the SQL Server role '{0}'. + SetProperties = Setting properties of the SQL Server role '{0}'. + TestProperties = Testing properties of the SQL Server role '{0}'. + EnumMemberNamesServerRoleGetError = Failed to enumerate members of the server role named '{2}' on '{0}\\{1}'. + MembersToIncludeAndExcludeParamMustBeNull = The parameter MembersToInclude and/or MembersToExclude must not be set, or be set to $null, when parameter Members are used. + DropServerRoleSetError = Failed to drop the server role named '{2}' on '{0}\\{1}'. + CreateServerRoleSetError = Failed to create the server role named '{2}' on '{0}\\{1}'. + AddMemberServerRoleSetError = Failed to add member '{3}' to the server role named '{2}' on '{0}\\{1}'. + DropMemberServerRoleSetError = Failed to drop member '{3}' to the server role named '{2}' on '{0}\\{1}'. + DesiredMembersNotPresent = One or more of the desired members are not present in the server role '{0}'. + MemberNotPresent = The login '{1}' is not a member of the server role '{0}'. + MemberPresent = The login '{1}' should not be a member of the server role '{0}'. + DropRole = Removing the SQL Server role '{0}'. + CreateRole = Creating the SQL Server role '{0}'. + EnsureIsAbsent = Ensure is set to Absent. The existing role '{0}' should be removed. + EnsureIsPresent = Ensure is set to Present. Either the role '{0}' is missing and should be created, or members in the role is not in desired state. + LoginNotFound = Login '{0}' does not exist on SQL server '{1}\\{2}'. + AddMemberToRole = Adding login '{0}' to role '{1}'. + RemoveMemberFromRole = Removing login '{0}' from role '{1}'. +'@ diff --git a/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServiceAccount/MSFT_SqlServiceAccount.psm1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServiceAccount/MSFT_SqlServiceAccount.psm1 new file mode 100644 index 000000000..a79b9c4ed --- /dev/null +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServiceAccount/MSFT_SqlServiceAccount.psm1 @@ -0,0 +1,442 @@ +Import-Module -Name (Join-Path -Path (Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent) ` + -ChildPath 'SqlServerDscHelper.psm1') + +Import-Module -Name (Join-Path -Path (Split-Path -Path $PSScriptRoot -Parent) ` + -ChildPath 'CommonResourceHelper.psm1') + +$script:localizedData = Get-LocalizedData -ResourceName 'MSFT_SqlServiceAccount' + +<# + .SYNOPSIS + Gets the service account for the specified instance. + + .PARAMETER ServerName + Host name of the SQL Server to manage. + + .PARAMETER InstanceName + Name of the SQL instance. + + .PARAMETER ServiceType + Type of service to be managed. Must be one of the following: + DatabaseEngine, SQLServerAgent, Search, IntegrationServices, AnalysisServices, ReportingServices, SQLServerBrowser, NotificationServices. + + .PARAMETER ServiceAccount + ** Not used in this function ** + Credential of the service account that should be used. + + .EXAMPLE + Get-TargetResource -ServerName $env:COMPUTERNAME -InstanceName MSSQLSERVER -ServiceType DatabaseEngine -ServiceAccount $account +#> +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $ServerName, + + [Parameter(Mandatory = $true)] + [System.String] + $InstanceName, + + [Parameter(Mandatory = $true)] + [ValidateSet('DatabaseEngine', 'SQLServerAgent', 'Search', 'IntegrationServices', 'AnalysisServices', 'ReportingServices', 'SQLServerBrowser', 'NotificationServices')] + [System.String] + $ServiceType, + + [Parameter(Mandatory = $true)] + [System.Management.Automation.PSCredential] + $ServiceAccount + ) + + # Get the SMO Service object instance + $serviceObject = Get-ServiceObject -ServerName $ServerName -InstanceName $InstanceName -ServiceType $ServiceType + + # If no service was found, throw an exception + if (-not $serviceObject) + { + $errorMessage = $script:localizedData.ServiceNotFound -f $ServiceType, $ServerName, $InstanceName + New-ObjectNotFoundException -Message $errorMessage + } + + # Local accounts will start with a '.' + # Replace a domain of '.' with the value for $ServerName + $serviceAccountName = $serviceObject.ServiceAccount -ireplace '^([\.])\\(.*)$', "$ServerName\`$2" + + # Return a hash table with the service information + return @{ + ServerName = $ServerName + InstanceName = $InstanceName + ServiceType = $serviceObject.Type + ServiceAccountName = $serviceAccountName + } +} + +<# + .SYNOPSIS + Tests whether the specified instance's service account is correctly configured. + + .PARAMETER ServerName + Host name of the SQL Server to manage. + + .PARAMETER InstanceName + Name of the SQL instance. + + .PARAMETER ServiceType + Type of service to be managed. Must be one of the following: + DatabaseEngine, SQLServerAgent, Search, IntegrationServices, AnalysisServices, ReportingServices, SQLServerBrowser, NotificationServices. + + .PARAMETER ServiceAccount + Credential of the service account that should be used. + + .PARAMETER RestartService + Determines whether the service is automatically restarted when a change + to the configuration was needed. + + .PARAMETER Force + Forces the service account to be updated. + + .EXAMPLE + Test-TargetResource -ServerName $env:COMPUTERNAME -InstanceName MSSQLSERVER -ServiceType DatabaseEngine -ServiceAccount $account + +#> +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $ServerName, + + [Parameter(Mandatory = $true)] + [System.String] + $InstanceName, + + [Parameter(Mandatory = $true)] + [ValidateSet('DatabaseEngine', 'SQLServerAgent', 'Search', 'IntegrationServices', 'AnalysisServices', 'ReportingServices', 'SQLServerBrowser', 'NotificationServices')] + [System.String] + $ServiceType, + + [Parameter(Mandatory = $true)] + [System.Management.Automation.PSCredential] + $ServiceAccount, + + [Parameter()] + [System.Boolean] + $RestartService, + + [Parameter()] + [System.Boolean] + $Force + ) + + if ($Force) + { + New-VerboseMessage -Message $script:localizedData.ForceServiceAccountUpdate + return $false + } + + # Get the current state + $currentState = Get-TargetResource -ServerName $ServerName -InstanceName $InstanceName -ServiceType $ServiceType -ServiceAccount $ServiceAccount + New-VerboseMessage -Message ($script:localizedData.CurrentServiceAccount -f $currentState.ServiceAccountName, $ServerName, $InstanceName) + + return ($currentState.ServiceAccountName -ieq $ServiceAccount.UserName) +} + +<# + .SYNOPSIS + Sets the SQL Server service account to the desired state. + + .PARAMETER ServerName + Host name of the SQL Server to manage. + + .PARAMETER InstanceName + Name of the SQL instance. + + .PARAMETER ServiceType + Type of service to be managed. Must be one of the following: + DatabaseEngine, SQLServerAgent, Search, IntegrationServices, AnalysisServices, ReportingServices, SQLServerBrowser, NotificationServices. + + .PARAMETER ServiceAccount + Credential of the service account that should be used. + + .PARAMETER RestartService + Determines whether the service is automatically restarted when a change + to the configuration was needed. + + .PARAMETER Force + Forces the service account to be updated. + + .EXAMPLE + Set-TargetResource -ServerName $env:COMPUTERNAME -InstanceName MSSQLSERVER -ServiceType DatabaseEngine -ServiceAccount $account +#> +function Set-TargetResource +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $ServerName, + + [Parameter(Mandatory = $true)] + [System.String] + $InstanceName, + + [Parameter(Mandatory = $true)] + [ValidateSet('DatabaseEngine', 'SQLServerAgent', 'Search', 'IntegrationServices', 'AnalysisServices', 'ReportingServices', 'SQLServerBrowser', 'NotificationServices')] + [System.String] + $ServiceType, + + [Parameter(Mandatory = $true)] + [System.Management.Automation.PSCredential] + $ServiceAccount, + + [Parameter()] + [System.Boolean] + $RestartService, + + [Parameter()] + [System.Boolean] + $Force + ) + + # Get the Service object + $serviceObject = Get-ServiceObject -ServerName $ServerName -InstanceName $InstanceName -ServiceType $ServiceType + + # If no service was found, throw an exception + if (-not $serviceObject) + { + $errorMessage = $script:localizedData.ServiceNotFound -f $ServiceType, $ServerName, $InstanceName + New-ObjectNotFoundException -Message $errorMessage + } + + try + { + New-VerboseMessage -Message ($script:localizedData.UpdatingServiceAccount -f $ServiceAccount.UserName, $serviceObject.Name) + $serviceObject.SetServiceAccount($ServiceAccount.UserName, $ServiceAccount.GetNetworkCredential().Password) + } + catch + { + $errorMessage = $script:localizedData.SetServiceAccountFailed -f $ServerName, $InstanceName, $_.Message + New-InvalidOperationException -Message $errorMessage -ErrorRecord $_ + } + + if ($RestartService) + { + New-VerboseMessage -Message ($script:localizedData.RestartingService -f $InstanceName) + Restart-SqlService -SQLServer $ServerName -SQLInstanceName $InstanceName + } +} + +<# + .SYNOPSIS + Gets an SMO Service object instance for the requested service and type. + + .PARAMETER ServerName + Host name of the SQL Server to manage. + + .PARAMETER InstanceName + Name of the SQL instance. + + .PARAMETER ServiceType + Type of service to be managed. Must be one of the following: + DatabaseEngine, SQLServerAgent, Search, IntegrationServices, AnalysisServices, ReportingServices, SQLServerBrowser, NotificationServices. + + .EXAMPLE + Get-ServiceObject -ServerName $env:COMPUTERNAME -InstanceName MSSQLSERVER -ServiceType DatabaseEngine +#> +function Get-ServiceObject +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $ServerName, + + [Parameter(Mandatory = $true)] + [System.String] + $InstanceName, + + [Parameter(Mandatory = $true)] + [ValidateSet('DatabaseEngine', 'SQLServerAgent', 'Search', 'IntegrationServices', 'AnalysisServices', 'ReportingServices', 'SQLServerBrowser', 'NotificationServices')] + [System.String] + $ServiceType + ) + + # Load the SMO libraries + Import-SQLPSModule + + $verboseMessage = $script:localizedData.ConnectingToWmi -f $ServerName + New-VerboseMessage -Message $verboseMessage + + # Connect to SQL WMI + $managedComputer = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer -ArgumentList $ServerName + + # Get the service name for the specified instance and type + $serviceNameFilter = Get-SqlServiceName -InstanceName $InstanceName -ServiceType $ServiceType + + # Get the Service object for the specified instance/type + $serviceObject = $managedComputer.Services | Where-Object -FilterScript { + $_.Name -eq $serviceNameFilter + } + + return $serviceObject +} + +<# + .SYNOPSIS + Converts the project's standard SQL Service types to the appropriate ManagedServiceType value + + .PARAMETER ServiceType + Type of service to be managed. Must be one of the following: + DatabaseEngine, SQLServerAgent, Search, IntegrationServices, AnalysisServices, ReportingServices, SQLServerBrowser, NotificationServices. + + .EXAMPLE + ConvertTo-ManagedServiceType -ServiceType 'DatabaseEngine' +#> +function ConvertTo-ManagedServiceType +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [ValidateSet('DatabaseEngine', 'SQLServerAgent', 'Search', 'IntegrationServices', 'AnalysisServices', 'ReportingServices', 'SQLServerBrowser', 'NotificationServices')] + [System.String] + $ServiceType + ) + + # Map the project-specific ServiceType to a valid value from the ManagedServiceType enumeration + switch ($ServiceType) + { + 'DatabaseEngine' + { + $serviceTypeValue = 'SqlServer' + } + + 'SQLServerAgent' + { + $serviceTypeValue = 'SqlAgent' + } + + 'Search' + { + $serviceTypeValue = 'Search' + } + + 'IntegrationServices' + { + $serviceTypeValue = 'SqlServerIntegrationService' + } + + 'AnalysisServices' + { + $serviceTypeValue = 'AnalysisServer' + } + + 'ReportingServices' + { + $serviceTypeValue = 'ReportServer' + } + + 'SQLServerBrowser' + { + $serviceTypeValue = 'SqlBrowser' + } + + 'NotificationServices' + { + $serviceTypeValue = 'NotificationServer' + } + } + + return $serviceTypeValue -as [Microsoft.SqlServer.Management.Smo.Wmi.ManagedServiceType] +} + +<# + .SYNOPSIS + Gets the name of a service based on the instance name and type. + + .PARAMETER InstanceName + Name of the SQL instance. + + .PARAMETER ServiceType + Type of service to be named. Must be one of the following: + DatabaseEngine, SQLServerAgent, Search, IntegrationServices, AnalysisServices, ReportingServices, SQLServerBrowser, NotificationServices. + + .EXAMPLE + Get-SqlServiceName -InstanceName 'MSSQLSERVER' -ServiceType ReportingServices +#> +function Get-SqlServiceName +{ + [CmdletBinding()] + param + ( + [Parameter()] + [System.String] + $InstanceName = 'MSSQLSERVER', + + [Parameter(Mandatory = $true)] + [ValidateSet('DatabaseEngine', 'SQLServerAgent', 'Search', 'IntegrationServices', 'AnalysisServices', 'ReportingServices', 'SQLServerBrowser', 'NotificationServices')] + [System.String] + $ServiceType + ) + + # Base path in the registry for service name definitions + $serviceRegistryKey = 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Services' + + # The value grabbed varies for a named vs default instance + if ($InstanceName -eq 'MSSQLSERVER') + { + $propertyName = 'Name' + $returnValue = '{0}' + } + else + { + $propertyName = 'LName' + $returnValue = '{0}{1}' + } + + # Map the specified type to a ManagedServiceType + $managedServiceType = ConvertTo-ManagedServiceType -ServiceType $ServiceType + + # Get the required naming property + $serviceTypeDefinition = Get-ChildItem -Path $serviceRegistryKey | Where-Object -FilterScript { + $_.GetValue('Type') -eq ($managedServiceType -as [int]) + } + + # Ensure we got a service definition + if ($serviceTypeDefinition) + { + # Multiple definitions found (thank you SQL Server Reporting Services!) + if ($serviceTypeDefinition.Count -gt 0) + { + $serviceNamingScheme = $serviceTypeDefinition | ForEach-Object -Process { + $_.GetValue($propertyName) + } | Select-Object -Unique + } + else + { + $serviceNamingScheme = $serviceTypeDefinition.GetValue($propertyName) + } + } + else + { + $errorMessage = $script:localizedData.UnknownServiceType -f $ServiceType + New-InvalidArgumentException -Message $errorMessage -ArgumentName 'ServiceType' + } + + if ([System.String]::IsNullOrEmpty($serviceNamingScheme)) + { + $errorMessage = $script:localizedData.NotInstanceAware -f $ServiceType + New-InvalidResultException -Message $errorMessage + } + + # Build the name of the service and return it + return ($returnValue -f $serviceNamingScheme, $InstanceName) +} diff --git a/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServiceAccount/MSFT_SqlServiceAccount.schema.mof b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServiceAccount/MSFT_SqlServiceAccount.schema.mof new file mode 100644 index 000000000..01e3d22f3 --- /dev/null +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServiceAccount/MSFT_SqlServiceAccount.schema.mof @@ -0,0 +1,11 @@ +[ClassVersion("1.0.0.0"), FriendlyName("SqlServiceAccount")] +class MSFT_SqlServiceAccount : OMI_BaseResource +{ + [Key, Description("Hostname of the SQL Server.")] String ServerName; + [Key, Description("Name of the SQL instance.")] String InstanceName; + [Key, Description("Type of service being managed."), ValueMap {"DatabaseEngine","SQLServerAgent","Search","IntegrationServices","AnalysisServices","ReportingServices","SQLServerBrowser","NotificationServices"}, Values {"DatabaseEngine","SQLServerAgent","Search","IntegrationServices","AnalysisServices","ReportingServices","SQLServerBrowser","NotificationServices"}] String ServiceType; + [Required, EmbeddedInstance("MSFT_Credential"), Description("The service account that should be used when running the service.")] String ServiceAccount; + [Write, Description("Determines whether the service is automatically restarted when a change to the configuration was needed.")] Boolean RestartService; + [Write, Description("Forces the service account to be updated. Useful for password changes.")] Boolean Force; + [Read, Description("Returns the service account username for the service.")] String ServiceAccountName; +}; diff --git a/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServiceAccount/en-US/MSFT_SqlServiceAccount.strings.psd1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServiceAccount/en-US/MSFT_SqlServiceAccount.strings.psd1 new file mode 100644 index 000000000..9facb6f92 --- /dev/null +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlServiceAccount/en-US/MSFT_SqlServiceAccount.strings.psd1 @@ -0,0 +1,13 @@ +# Localized resources for SqlServiceAccount + +ConvertFrom-StringData @' + ForceServiceAccountUpdate = Force specified, skipping tests. With this configuration, Test-TargetResource will always return 'False'. + CurrentServiceAccount = Current service account is '{0}' for {1}\\{2}. + ConnectingToWmi = Connecting to WMI on '{0}'. + UpdatingServiceAccount = Setting service account to '{0}' for service {1}. + RestartingService = Restarting '{0}' and any dependent services. + ServiceNotFound = The {0} service on {1}\\{2} could not be found. + SetServiceAccountFailed = Unable to set the service account for {0} on {1}. Message {2} + UnknownServiceType = Unknown or unsupported service type '{0}' specified! + NotInstanceAware = Service type '{0}' is not instance aware. +'@ diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerSetup/MSFT_xSQLServerSetup.psm1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlSetup/MSFT_SqlSetup.psm1 similarity index 75% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerSetup/MSFT_xSQLServerSetup.psm1 rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlSetup/MSFT_SqlSetup.psm1 index c741bc442..d300acef1 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerSetup/MSFT_xSQLServerSetup.psm1 +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlSetup/MSFT_SqlSetup.psm1 @@ -1,6 +1,10 @@ -$script:currentPath = Split-Path -Path $MyInvocation.MyCommand.Path -Parent -Import-Module -Name (Join-Path -Path (Split-Path -Path (Split-Path -Path $script:currentPath -Parent) -Parent) -ChildPath 'xSQLServerHelper.psm1') -Import-Module -Name (Join-Path -Path (Split-Path -Path (Split-Path -Path $script:currentPath -Parent) -Parent) -ChildPath 'xPDT.psm1') +Import-Module -Name (Join-Path -Path (Split-Path -Path (Split-Path -Path $PSScriptRoot -Parent) -Parent) ` + -ChildPath 'SqlServerDscHelper.psm1') + +Import-Module -Name (Join-Path -Path (Split-Path -Path $PSScriptRoot -Parent) ` + -ChildPath 'CommonResourceHelper.psm1') + +$script:localizedData = Get-LocalizedData -ResourceName 'MSFT_SqlSetup' <# .SYNOPSIS @@ -13,9 +17,6 @@ Import-Module -Name (Join-Path -Path (Split-Path -Path (Split-Path -Path $script .PARAMETER SourcePath The path to the root of the source files for installation. I.e and UNC path to a shared resource. Environment variables can be used in the path. - .PARAMETER SetupCredential - Credential to be used to perform the installation. - .PARAMETER SourceCredential Credentials used to access the path set in the parameter `SourcePath`. Using this parameter will trigger a copy of the installation media to a temp folder on the target node. Setup will then be started from the temp folder on the target node. @@ -46,10 +47,6 @@ function Get-TargetResource [System.String] $SourcePath, - [Parameter(Mandatory = $true)] - [System.Management.Automation.PSCredential] - $SetupCredential, - [Parameter()] [System.Management.Automation.PSCredential] $SourceCredential, @@ -89,7 +86,7 @@ function Get-TargetResource $pathToSetupExecutable = Join-Path -Path $SourcePath -ChildPath 'setup.exe' - New-VerboseMessage -Message "Using path: $pathToSetupExecutable" + Write-Verbose -Message ($script:localizedData.UsingPath -f $pathToSetupExecutable) $sqlVersion = Get-SqlMajorVersion -Path $pathToSetupExecutable @@ -118,13 +115,15 @@ function Get-TargetResource $integrationServiceName = "MsDtsServer$($sqlVersion)0" $features = '' - $clusteredSqlGroupName = '' - $clusteredSqlHostname = '' - $clusteredSqlIPAddress = '' $services = Get-Service + + Write-Verbose -Message $script:localizedData.EvaluateDatabaseEngineFeature + if ($services | Where-Object {$_.Name -eq $databaseServiceName}) { + Write-Verbose -Message $script:localizedData.DatabaseEngineFeatureFound + $features += 'SQLENGINE,' $sqlServiceAccountUsername = (Get-CimInstance -ClassName Win32_Service -Filter "Name = '$databaseServiceName'").StartName @@ -133,41 +132,51 @@ function Get-TargetResource $fullInstanceId = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL' -Name $InstanceName).$InstanceName # Check if Replication sub component is configured for this instance - New-VerboseMessage -Message "Detecting replication feature (HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$fullInstanceId\ConfigurationState)" - $isReplicationInstalled = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$fullInstanceId\ConfigurationState").SQL_Replication_Core_Inst + $replicationRegistryPath = "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$fullInstanceId\ConfigurationState" + + Write-Verbose -Message ($script:localizedData.EvaluateReplicationFeature -f $replicationRegistryPath) + + $isReplicationInstalled = (Get-ItemProperty -Path $replicationRegistryPath).SQL_Replication_Core_Inst if ($isReplicationInstalled -eq 1) { - New-VerboseMessage -Message 'Replication feature detected' + Write-Verbose -Message $script:localizedData.ReplicationFeatureFound $features += 'REPLICATION,' } else { - New-VerboseMessage -Message 'Replication feature not detected' + Write-Verbose -Message $script:localizedData.ReplicationFeatureNotFound } - $clientComponentsFullRegistryPath = "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$($sqlVersion)0\Tools\Setup\Client_Components_Full" - $registryClientComponentsFullFeatureList = (Get-ItemProperty -Path $clientComponentsFullRegistryPath -ErrorAction SilentlyContinue).FeatureList + # Check if Data Quality Client sub component is configured + $dataQualityClientRegistryPath = "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$($sqlVersion)0\ConfigurationState" - Write-Debug -Message "Detecting Client Connectivity Tools feature ($clientComponentsFullRegistryPath)" - if ($registryClientComponentsFullFeatureList -like '*Connectivity_FNS=3*') + Write-Verbose -Message ($script:localizedData.EvaluateDataQualityClientFeature -f $dataQualityClientRegistryPath) + + $isDQCInstalled = (Get-ItemProperty -Path $dataQualityClientRegistryPath).SQL_DQ_CLIENT_Full + if ($isDQCInstalled -eq 1) { - New-VerboseMessage -Message 'Client Connectivity Tools feature detected' - $features += 'CONN,' + Write-Verbose -Message $script:localizedData.DataQualityClientFeatureFound + $features += 'DQC,' } else { - New-VerboseMessage -Message 'Client Connectivity Tools feature not detected' + Write-Verbose -Message $script:localizedData.DataQualityClientFeatureNotFound } - Write-Debug -Message "Detecting Client Connectivity Backwards Compatibility Tools feature ($clientComponentsFullRegistryPath)" - if ($registryClientComponentsFullFeatureList -like '*Tools_Legacy_FNS=3*') + # Check if Data Quality Services sub component is configured + $dataQualityServicesRegistryPath = "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$($sqlVersion)0\DQ\*" + + Write-Verbose -Message ($script:localizedData.EvaluateDataQualityServicesFeature -f $dataQualityServicesRegistryPath) + + $isDQInstalled = (Get-ItemProperty -Path $dataQualityServicesRegistryPath -ErrorAction SilentlyContinue) + if ($isDQInstalled) { - New-VerboseMessage -Message 'Client Connectivity Tools Backwards Compatibility feature detected' - $features += 'BC,' + Write-Verbose -Message $script:localizedData.DataQualityServicesFeatureFound + $features += 'DQ,' } else { - New-VerboseMessage -Message 'Client Connectivity Tools Backwards Compatibility feature not detected' + Write-Verbose -Message $script:localizedData.DataQualityServicesFeatureNotFound } $instanceId = $fullInstanceId.Split('.')[1] @@ -205,17 +214,18 @@ function Get-TargetResource if ($databaseServer.IsClustered) { - New-VerboseMessage -Message 'Clustered instance detected' + Write-Verbose -Message $script:localizedData.ClusterInstanceFound $clusteredSqlInstance = Get-CimInstance -Namespace root/MSCluster -ClassName MSCluster_Resource -Filter "Type = 'SQL Server'" | Where-Object { $_.PrivateProperties.InstanceName -eq $InstanceName } if (!$clusteredSqlInstance) { - throw New-TerminatingError -ErrorType FailoverClusterResourceNotFound -FormatArgs $InstanceName -ErrorCategory 'ObjectNotFound' + $errorMessage = $script:localizedData.FailoverClusterResourceNotFound -f $InstanceName + New-ObjectNotFoundException -Message $errorMessage } - New-VerboseMessage -Message 'Clustered SQL Server resource located' + Write-Verbose -Message $script:localizedData.FailoverClusterResourceFound $clusteredSqlGroup = $clusteredSqlInstance | Get-CimAssociatedInstance -ResultClassName MSCluster_ResourceGroup $clusteredSqlNetworkName = $clusteredSqlGroup | Get-CimAssociatedInstance -ResultClassName MSCluster_Resource | @@ -230,24 +240,48 @@ function Get-TargetResource } else { - New-VerboseMessage -Message 'Clustered instance not detected' + Write-Verbose -Message $script:localizedData.ClusterInstanceNotFound } } + else + { + Write-Verbose -Message $script:localizedData.DatabaseEngineFeatureNotFound + } + + Write-Verbose -Message $script:localizedData.EvaluateFullTextFeature if ($services | Where-Object {$_.Name -eq $fullTextServiceName}) { + Write-Verbose -Message $script:localizedData.FullTextFeatureFound + $features += 'FULLTEXT,' - $fulltextServiceAccountUsername = (Get-CimInstance -ClassName Win32_Service -Filter "Name = '$fullTextServiceName'").StartName + $fullTextServiceAccountUsername = (Get-CimInstance -ClassName Win32_Service -Filter "Name = '$fullTextServiceName'").StartName + } + else + { + Write-Verbose -Message $script:localizedData.FullTextFeatureNotFound } + Write-Verbose -Message $script:localizedData.EvaluateReportingServicesFeature + if ($services | Where-Object {$_.Name -eq $reportServiceName}) { + Write-Verbose -Message $script:localizedData.ReportingServicesFeatureFound + $features += 'RS,' $reportingServiceAccountUsername = (Get-CimInstance -ClassName Win32_Service -Filter "Name = '$reportServiceName'").StartName } + else + { + Write-Verbose -Message $script:localizedData.ReportingServicesFeatureNotFound + } + + Write-Verbose -Message $script:localizedData.EvaluateAnalysisServicesFeature if ($services | Where-Object {$_.Name -eq $analysisServiceName}) { + Write-Verbose -Message $script:localizedData.AnalysisServicesFeatureFound + $features += 'AS,' $analysisServiceAccountUsername = (Get-CimInstance -ClassName Win32_Service -Filter "Name = '$analysisServiceName'").StartName @@ -259,16 +293,106 @@ function Get-TargetResource $analysisLogDirectory = $analysisServer.ServerProperties['LogDir'].Value $analysisBackupDirectory = $analysisServer.ServerProperties['BackupDir'].Value - $analysisSystemAdminAccounts = $analysisServer.Roles['Administrators'].Members.Name + <# + The property $analysisServer.ServerMode.value__ contains the + server mode (aka deployment mode) value 0, 1 or 2. See DeploymentMode + here https://docs.microsoft.com/en-us/sql/analysis-services/server-properties/general-properties. + + The property $analysisServer.ServerMode contains the display name of + the property value__. See more information here + https://msdn.microsoft.com/en-us/library/microsoft.analysisservices.core.server.servermode.aspx. + #> + $analysisServerMode = $analysisServer.ServerMode.ToString().ToUpper() + + $analysisSystemAdminAccounts = [System.String[]] $analysisServer.Roles['Administrators'].Members.Name $analysisConfigDirectory = (Get-ItemProperty -Path "HKLM:\SYSTEM\CurrentControlSet\Services\$analysisServiceName" -Name 'ImagePath').ImagePath.Replace(' -s ',',').Split(',')[1].Trim('"') } + else + { + Write-Verbose -Message $script:localizedData.AnalysisServicesFeatureNotFound + } + + Write-Verbose -Message $script:localizedData.EvaluateIntegrationServicesFeature if ($services | Where-Object {$_.Name -eq $integrationServiceName}) { + Write-Verbose -Message $script:localizedData.IntegrationServicesFeatureFound + $features += 'IS,' $integrationServiceAccountUsername = (Get-CimInstance -ClassName Win32_Service -Filter "Name = '$integrationServiceName'").StartName } + else + { + Write-Verbose -Message $script:localizedData.IntegrationServicesFeatureNotFound + } + + # Check if Documentation Components "BOL" is configured + $documentationComponentsRegistryPath = "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$($sqlVersion)0\ConfigurationState" + + Write-Verbose -Message ($script:localizedData.EvaluateDocumentationComponentsFeature -f $documentationComponentsRegistryPath) + + $isBOLInstalled = (Get-ItemProperty -Path $documentationComponentsRegistryPath -ErrorAction SilentlyContinue).SQL_BOL_Components + if ($isBOLInstalled -eq 1) + { + Write-Verbose -Message $script:localizedData.DocumentationComponentsFeatureFound + $features += 'BOL,' + } + else + { + Write-Verbose -Message $script:localizedData.DocumentationComponentsFeatureNotFound + } + + $clientComponentsFullRegistryPath = "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$($sqlVersion)0\Tools\Setup\Client_Components_Full" + $registryClientComponentsFullFeatureList = (Get-ItemProperty -Path $clientComponentsFullRegistryPath -ErrorAction SilentlyContinue).FeatureList + + Write-Verbose -Message ($script:localizedData.EvaluateClientConnectivityToolsFeature -f $clientComponentsFullRegistryPath) + + if ($registryClientComponentsFullFeatureList -like '*Connectivity_FNS=3*') + { + Write-Verbose -Message $script:localizedData.ClientConnectivityToolsFeatureFound + $features += 'CONN,' + } + else + { + Write-Verbose -Message $script:localizedData.ClientConnectivityToolsFeatureNotFound + } + + Write-Verbose -Message ($script:localizedData.EvaluateClientConnectivityBackwardsCompatibilityToolsFeature -f $clientComponentsFullRegistryPath) + if ($registryClientComponentsFullFeatureList -like '*Tools_Legacy_FNS=3*') + { + Write-Verbose -Message $script:localizedData.ClientConnectivityBackwardsCompatibilityToolsFeatureFound + $features += 'BC,' + } + else + { + Write-Verbose -Message $script:localizedData.ClientConnectivityBackwardsCompatibilityToolsFeatureNotFound + } + + Write-Verbose -Message ($script:localizedData.EvaluateClientToolsSdkFeature -f $clientComponentsFullRegistryPath) + if (($registryClientComponentsFullFeatureList -like '*SDK_Full=3*') -and ($registryClientComponentsFullFeatureList -like '*SDK_FNS=3*')) + { + Write-Verbose -Message $script:localizedData.ClientToolsSdkFeatureFound + $features += 'SDK,' + } + else + { + Write-Verbose -Message $script:localizedData.ClientToolsSdkFeatureNotFound + } + + # Check if MDS sub component is configured for this server + $masterDataServicesFullRegistryPath = "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$($sqlVersion)0\ConfigurationState" + Write-Verbose -Message ($script:localizedData.EvaluateMasterDataServicesFeature -f $masterDataServicesFullRegistryPath) + $isMDSInstalled = (Get-ItemProperty -Path $masterDataServicesFullRegistryPath -ErrorAction SilentlyContinue).MDSCoreFeature + if ($isMDSInstalled -eq 1) + { + Write-Verbose -Message $script:localizedData.MasterDataServicesFeatureFound + $features += 'MDS,' + } + else + { + Write-Verbose -Message $script:localizedData.MasterDataServicesFeatureNotFound + } $registryUninstallPath = 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall' @@ -321,31 +445,13 @@ function Get-TargetResource } $features = $features.Trim(',') - if ($features -ne '') + if ($features) { $registryInstallerComponentsPath = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components' switch ($sqlVersion) { - '10' - { - $registryKeySharedDir = '0D1F366D0FE0E404F8C15EE4F1C15094' - $registryKeySharedWOWDir = 'C90BFAC020D87EA46811C836AD3C507F' - } - - '11' - { - $registryKeySharedDir = 'FEE2E540D20152D4597229B6CFBC0A69' - $registryKeySharedWOWDir = 'A79497A344129F64CA7D69C56F5DD8B4' - } - - '12' - { - $registryKeySharedDir = 'FEE2E540D20152D4597229B6CFBC0A69' - $registryKeySharedWOWDir = 'C90BFAC020D87EA46811C836AD3C507F' - } - - { $_ -in ('13','14') } + { $_ -in ('10','11','12','13','14') } { $registryKeySharedDir = 'FEE2E540D20152D4597229B6CFBC0A69' $registryKeySharedWOWDir = 'A79497A344129F64CA7D69C56F5DD8B4' @@ -382,7 +488,7 @@ function Get-TargetResource SQLTempDBDir = $null SQLTempDBLogDir = $null SQLBackupDir = $sqlBackupDirectory - FTSvcAccountUsername = $fulltextServiceAccountUsername + FTSvcAccountUsername = $fullTextServiceAccountUsername RSSvcAccountUsername = $reportingServiceAccountUsername ASSvcAccountUsername = $analysisServiceAccountUsername ASCollation = $analysisCollation @@ -392,6 +498,7 @@ function Get-TargetResource ASBackupDir = $analysisBackupDirectory ASTempDir = $analysisTempDirectory ASConfigDir = $analysisConfigDirectory + ASServerMode = $analysisServerMode ISSvcAccountUsername = $integrationServiceAccountUsername FailoverClusterGroupName = $clusteredSqlGroupName FailoverClusterNetworkName = $clusteredSqlHostname @@ -410,9 +517,6 @@ function Get-TargetResource .PARAMETER SourcePath The path to the root of the source files for installation. I.e and UNC path to a shared resource. Environment variables can be used in the path. - .PARAMETER SetupCredential - Credential to be used to perform the installation. - .PARAMETER SourceCredential Credentials used to access the path set in the parameter `SourcePath`. Using this parameter will trigger a copy of the installation media to a temp folder on the target node. Setup will then be started from the temp folder on the target node. @@ -527,6 +631,13 @@ function Get-TargetResource .PARAMETER ASConfigDir Path for Analysis Services config. + .PARAMETER ASServerMode + The server mode for SQL Server Analysis Services instance. The default is + to install in Multidimensional mode. Valid values in a cluster scenario + are MULTIDIMENSIONAL or TABULAR. Parameter ASServerMode is case-sensitive. + All values must be expressed in upper case. + { MULTIDIMENSIONAL | TABULAR | POWERPIVOT }. + .PARAMETER ISSvcAccount Service account for Integration Services service. @@ -541,11 +652,22 @@ function Get-TargetResource .PARAMETER FailoverClusterNetworkName Host name to be assigned to the clustered SQL Server instance + + .PARAMETER SetupProcessTimeout + The timeout, in seconds, to wait for the setup process to finish. Default value is 7200 seconds (2 hours). If the setup process does not finish before this time, and error will be thrown. #> function Set-TargetResource { - # Suppressing this rule because $global:DSCMachineStatus is used to trigger a reboot, either by force or when there are pending changes. + <# + Suppressing this rule because $global:DSCMachineStatus is used to trigger + a reboot, either by force or when there are pending changes. + #> [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSAvoidGlobalVars', '')] + <# + Suppressing this rule because $global:DSCMachineStatus is only set, + never used (by design of Desired State Configuration). + #> + [System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '', Scope='Function', Target='DSCMachineStatus')] [CmdletBinding()] param ( @@ -558,10 +680,6 @@ function Set-TargetResource [System.String] $SourcePath, - [Parameter(Mandatory = $true)] - [System.Management.Automation.PSCredential] - $SetupCredential, - [Parameter()] [System.Management.Automation.PSCredential] $SourceCredential, @@ -706,6 +824,11 @@ function Set-TargetResource [System.String] $ASConfigDir, + [Parameter()] + [ValidateSet('MULTIDIMENSIONAL','TABULAR','POWERPIVOT', IgnoreCase = $false)] + [System.String] + $ASServerMode, + [Parameter()] [System.Management.Automation.PSCredential] $ISSvcAccount, @@ -725,13 +848,16 @@ function Set-TargetResource [Parameter()] [System.String] - $FailoverClusterNetworkName + $FailoverClusterNetworkName, + + [Parameter()] + [System.UInt32] + $SetupProcessTimeout = 7200 ) $getTargetResourceParameters = @{ Action = $Action SourcePath = $SourcePath - SetupCredential = $SetupCredential SourceCredential = $SourceCredential InstanceName = $InstanceName FailoverClusterNetworkName = $FailoverClusterNetworkName @@ -755,7 +881,8 @@ function Set-TargetResource 'ASLogDir', 'ASBackupDir', 'ASTempDir', - 'ASConfigDir' + 'ASConfigDir', + 'UpdateSource' ) # Remove trailing slash ('\') from paths @@ -800,8 +927,8 @@ function Set-TargetResource $mediaDestinationPath = Join-Path -Path (Get-TemporaryFolder) -ChildPath $mediaDestinationFolder - New-VerboseMessage -Message "Robocopy is copying media from source '$SourcePath' to destination '$mediaDestinationPath'" - Copy-ItemWithRoboCopy -Path $SourcePath -DestinationPath $mediaDestinationPath + Write-Verbose -Message ($script:localizedData.RobocopyIsCopying -f $SourcePath, $mediaDestinationPath) + Copy-ItemWithRobocopy -Path $SourcePath -DestinationPath $mediaDestinationPath Remove-SmbMapping -RemotePath $SourcePath -Force @@ -810,20 +937,21 @@ function Set-TargetResource $pathToSetupExecutable = Join-Path -Path $SourcePath -ChildPath 'setup.exe' - New-VerboseMessage -Message "Using path: $pathToSetupExecutable" + Write-Verbose -Message ($script:localizedData.UsingPath -f $pathToSetupExecutable) $sqlVersion = Get-SqlMajorVersion -Path $pathToSetupExecutable # Determine features to install - $featuresToInstall = "" - foreach ($feature in $Features.Split(",")) + $featuresToInstall = '' + foreach ($feature in $Features.Split(',')) { # Given that all the returned features are uppercase, make sure that the feature to search for is also uppercase $feature = $feature.ToUpper(); if (($sqlVersion -in ('13','14')) -and ($feature -in ('ADV_SSMS','SSMS'))) { - Throw New-TerminatingError -ErrorType FeatureNotSupported -FormatArgs @($feature) -ErrorCategory InvalidData + $errorMessage = $script:localizedData.FeatureNotSupported -f $feature + New-InvalidOperationException -Message $errorMessage } if (-not ($getTargetResourceResult.Features.Contains($feature))) @@ -837,46 +965,7 @@ function Set-TargetResource # If SQL shared components already installed, clear InstallShared*Dir variables switch ($sqlVersion) { - '10' - { - if((Get-Variable -Name 'InstallSharedDir' -ErrorAction SilentlyContinue) -and (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\0D1F366D0FE0E404F8C15EE4F1C15094' -ErrorAction SilentlyContinue)) - { - Set-Variable -Name 'InstallSharedDir' -Value '' - } - - if((Get-Variable -Name 'InstallSharedWOWDir' -ErrorAction SilentlyContinue) -and (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\C90BFAC020D87EA46811C836AD3C507F' -ErrorAction SilentlyContinue)) - { - Set-Variable -Name 'InstallSharedWOWDir' -Value '' - } - } - - '11' - { - if((Get-Variable -Name 'InstallSharedDir' -ErrorAction SilentlyContinue) -and (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\30AE1F084B1CF8B4797ECB3CCAA3B3B6' -ErrorAction SilentlyContinue)) - { - Set-Variable -Name 'InstallSharedDir' -Value '' - } - - if((Get-Variable -Name 'InstallSharedWOWDir' -ErrorAction SilentlyContinue) -and (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\A79497A344129F64CA7D69C56F5DD8B4' -ErrorAction SilentlyContinue)) - { - Set-Variable -Name 'InstallSharedWOWDir' -Value '' - } - } - - '12' - { - if((Get-Variable -Name 'InstallSharedDir' -ErrorAction SilentlyContinue) -and (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\FEE2E540D20152D4597229B6CFBC0A69' -ErrorAction SilentlyContinue)) - { - Set-Variable -Name 'InstallSharedDir' -Value '' - } - - if((Get-Variable -Name 'InstallSharedWOWDir' -ErrorAction SilentlyContinue) -and (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\C90BFAC020D87EA46811C836AD3C507F' -ErrorAction SilentlyContinue)) - { - Set-Variable -Name 'InstallSharedWOWDir' -Value '' - } - } - - { $_ -in ('13','14') } + { $_ -in ('10','11','12','13','14') } { if((Get-Variable -Name 'InstallSharedDir' -ErrorAction SilentlyContinue) -and (Get-ItemProperty 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\FEE2E540D20152D4597229B6CFBC0A69' -ErrorAction SilentlyContinue)) { @@ -940,7 +1029,7 @@ function Set-TargetResource $parameterValue = Get-Variable -Name $parameterName -ValueOnly if ($parameterValue) { - New-VerboseMessage -Message ("Found assigned parameter '{0}'. Adding path '{1}' to list of paths that required cluster drive." -f $parameterName, $parameterValue) + Write-Verbose -Message ($script:localizedData.PathRequireClusterDriveFound -f $parameterName, $parameterValue) $requiredDrive += $parameterValue } } @@ -1021,7 +1110,8 @@ function Set-TargetResource $unMappedRequiredDrives = $requiredDrive | Where-Object {$_.IsMapped -eq $false} | Measure-Object if ($unMappedRequiredDrives.Count -gt 0) { - throw New-TerminatingError -ErrorType FailoverClusterDiskMappingError -FormatArgs ($failoverClusterDisks -join '; ') -ErrorCategory InvalidResult + $errorMessage = $script:localizedData.FailoverClusterDiskMappingError -f ($failoverClusterDisks -join '; ') + New-InvalidResultException -Message $errorMessage } # Add the cluster disks as a setup argument @@ -1065,7 +1155,8 @@ function Set-TargetResource # Determine whether we have mapping issues for the IP Address(es) if ($mappedNetworkCount -lt $suppliedNetworkCount) { - throw New-TerminatingError -ErrorType FailoverClusterIPAddressNotValid -ErrorCategory InvalidArgument + $errorMessage = $script:localizedData.FailoverClusterIPAddressNotValid + New-InvalidResultException -Message $errorMessage } # Add the networks to the installation arguments @@ -1125,7 +1216,16 @@ function Set-TargetResource # Should not be passed when PrepareFailoverCluster is specified if ($Action -in @('Install','InstallFailoverCluster','CompleteFailoverCluster')) { - $setupArguments += @{ SQLSysAdminAccounts = @($SetupCredential.UserName) } + if ($null -ne $PsDscContext.RunAsUser) + { + <# + Add the credentials from the parameter PsDscRunAsCredential, as the first + system administrator. The username is stored in $PsDscContext.RunAsUser. + #> + Write-Verbose -Message ($script:localizedData.AddingFirstSystemAdministratorSqlServer -f $($PsDscContext.RunAsUser)) + $setupArguments += @{ SQLSysAdminAccounts = @($PsDscContext.RunAsUser) } + } + if ($PSBoundParameters.ContainsKey('SQLSysAdminAccounts')) { $setupArguments['SQLSysAdminAccounts'] += $SQLSysAdminAccounts @@ -1176,6 +1276,12 @@ function Set-TargetResource 'ASConfigDir' ) + + if ($PSBoundParameters.ContainsKey('ASServerMode')) + { + $setupArguments['ASServerMode'] = $ASServerMode + } + if ($PSBoundParameters.ContainsKey('ASSvcAccount')) { $setupArguments += (Get-ServiceAccountParameters -ServiceAccount $ASSvcAccount -ServiceType 'AS') @@ -1183,7 +1289,15 @@ function Set-TargetResource if ($Action -in ('Install','InstallFailoverCluster','CompleteFailoverCluster')) { - $setupArguments += @{ ASSysAdminAccounts = @($SetupCredential.UserName) } + if ($null -ne $PsDscContext.RunAsUser) + { + <# + Add the credentials from the parameter PsDscRunAsCredential, as the first + system administrator. The username is stored in $PsDscContext.RunAsUser. + #> + Write-Verbose -Message ($script:localizedData.AddingFirstSystemAdministratorAnalysisServices -f $($PsDscContext.RunAsUser)) + $setupArguments += @{ ASSysAdminAccounts = @($PsDscContext.RunAsUser) } + } if($PSBoundParameters.ContainsKey("ASSysAdminAccounts")) { @@ -1209,7 +1323,11 @@ function Set-TargetResource } else { - $setupArguments += @{ $argument = (Get-Variable -Name $argument -ValueOnly) } + # If the argument contains a value, then add the argument to the setup argument list + if (Get-Variable -Name $argument -ValueOnly) + { + $setupArguments += @{ $argument = (Get-Variable -Name $argument -ValueOnly) } + } } } @@ -1220,12 +1338,12 @@ function Set-TargetResource if ($currentSetupArgument.Value -ne '') { # Arrays are handled specially - if ($currentSetupArgument.Value -is [array]) + if ($currentSetupArgument.Value -is [System.Array]) { # Sort and format the array $setupArgumentValue = ($currentSetupArgument.Value | Sort-Object | ForEach-Object { '"{0}"' -f $_ }) -join ' ' } - elseif ($currentSetupArgument.Value -is [Boolean]) + elseif ($currentSetupArgument.Value -is [System.Boolean]) { $setupArgumentValue = @{ $true = 'True'; $false = 'False' }[$currentSetupArgument.Value] $setupArgumentValue = '"{0}"' -f $setupArgumentValue @@ -1269,40 +1387,69 @@ function Set-TargetResource } } - New-VerboseMessage -Message "Starting setup using arguments: $log" - $arguments = $arguments.Trim() - $processArguments = @{ - Path = $pathToSetupExecutable - Arguments = $arguments - } - if ($Action -in @('InstallFailoverCluster','AddNode')) + try { - $processArguments.Add('Credential',$SetupCredential) - } + Write-Verbose -Message ($script:localizedData.SetupArguments -f $log) - $process = StartWin32Process @processArguments + <# + This handles when PsDscRunAsCredential is set, or running as the SYSTEM account (when + PsDscRunAsCredential is not set). + #> - New-VerboseMessage -Message $process + $startProcessParameters = @{ + FilePath = $pathToSetupExecutable + ArgumentList = $arguments + Timeout = $SetupProcessTimeout + } - WaitForWin32ProcessEnd -Path $pathToSetupExecutable -Arguments $arguments + $processExitCode = Start-SqlSetupProcess @startProcessParameters - if ($ForceReboot -or ($null -ne (Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager' -Name 'PendingFileRenameOperations' -ErrorAction SilentlyContinue))) - { - if (-not ($SuppressReboot)) + $setupExitMessage = ($script:localizedData.SetupExitMessage -f $processExitCode) + + if ($processExitCode -eq 3010 -and -not $SuppressReboot) { - $global:DSCMachineStatus = 1 + $setupExitMessageRebootRequired = ('{0} {1}' -f $setupExitMessage, ($script:localizedData.SetupSuccessfulRebootRequired)) + + Write-Warning -Message $setupExitMessageRebootRequired + } + elseif ($processExitCode -ne 0) + { + $setupExitMessageError = ('{0} {1}' -f $setupExitMessage, ($script:localizedData.SetupFailed)) + + Write-Warning $setupExitMessageError } else { - New-VerboseMessage -Message 'Suppressing reboot' + $setupExitMessageSuccessful = ('{0} {1}' -f $setupExitMessage, ($script:localizedData.SetupSuccessful)) + + Write-Verbose -Message $setupExitMessageSuccessful + } + + if ($ForceReboot -or ($null -ne (Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager' -Name 'PendingFileRenameOperations' -ErrorAction SilentlyContinue))) + { + if (-not ($SuppressReboot)) + { + Write-Verbose -Message $script:localizedData.Reboot + + $global:DSCMachineStatus = 1 + } + else + { + Write-Verbose -Message $script:localizedData.SuppressReboot + } } - } - if (-not (Test-TargetResource @PSBoundParameters)) + if (-not (Test-TargetResource @PSBoundParameters)) + { + $errorMessage = $script:localizedData.TestFailedAfterSet + New-InvalidResultException -Message $errorMessage + } + } + catch { - throw New-TerminatingError -ErrorType TestFailedAfterSet -ErrorCategory InvalidResult + throw $_ } } @@ -1317,9 +1464,6 @@ function Set-TargetResource .PARAMETER SourcePath The path to the root of the source files for installation. I.e and UNC path to a shared resource. Environment variables can be used in the path. - .PARAMETER SetupCredential - Credential to be used to perform the installation. - .PARAMETER SourceCredential Credentials used to access the path set in the parameter `SourcePath`. Using this parameter will trigger a copy of the installation media to a temp folder on the target node. Setup will then be started from the temp folder on the target node. @@ -1434,6 +1578,13 @@ function Set-TargetResource .PARAMETER ASConfigDir Path for Analysis Services config. + .PARAMETER ASServerMode + The server mode for SQL Server Analysis Services instance. The default is + to install in Multidimensional mode. Valid values in a cluster scenario + are MULTIDIMENSIONAL or TABULAR. Parameter ASServerMode is case-sensitive. + All values must be expressed in upper case. + { MULTIDIMENSIONAL | TABULAR | POWERPIVOT }. + .PARAMETER ISSvcAccount Service account for Integration Services service. @@ -1448,6 +1599,9 @@ function Set-TargetResource .PARAMETER FailoverClusterNetworkName Host name to be assigned to the clustered SQL Server instance + + .PARAMETER SetupProcessTimeout + The timeout, in seconds, to wait for the setup process to finish. Default value is 7200 seconds (2 hours). If the setup process does not finish before this time, and error will be thrown. #> function Test-TargetResource { @@ -1464,10 +1618,6 @@ function Test-TargetResource [System.String] $SourcePath, - [Parameter(Mandatory = $true)] - [System.Management.Automation.PSCredential] - $SetupCredential, - [Parameter()] [System.Management.Automation.PSCredential] $SourceCredential, @@ -1612,6 +1762,11 @@ function Test-TargetResource [System.String] $ASConfigDir, + [Parameter()] + [ValidateSet('MULTIDIMENSIONAL','TABULAR','POWERPIVOT', IgnoreCase = $false)] + [System.String] + $ASServerMode, + [Parameter()] [System.Management.Automation.PSCredential] $ISSvcAccount, @@ -1631,13 +1786,16 @@ function Test-TargetResource [Parameter(ParameterSetName = 'ClusterInstall')] [System.String] - $FailoverClusterNetworkName + $FailoverClusterNetworkName, + + [Parameter()] + [System.UInt32] + $SetupProcessTimeout = 7200 ) $getTargetResourceParameters = @{ Action = $Action SourcePath = $SourcePath - SetupCredential = $SetupCredential SourceCredential = $SourceCredential InstanceName = $InstanceName FailoverClusterNetworkName = $FailoverClusterNetworkName @@ -1646,7 +1804,7 @@ function Test-TargetResource $boundParameters = $PSBoundParameters $getTargetResourceResult = Get-TargetResource @getTargetResourceParameters - New-VerboseMessage -Message "Features found: '$($getTargetResourceResult.Features)'" + Write-Verbose -Message ($script:localizedData.FeaturesFound -f $($getTargetResourceResult.Features)) $result = $true @@ -1659,7 +1817,7 @@ function Test-TargetResource if(!($getTargetResourceResult.Features.Contains($feature))) { - New-VerboseMessage -Message "Unable to find feature '$feature' among the installed features: '$($getTargetResourceResult.Features)'" + Write-Verbose -Message ($script:localizedData.UnableToFindFeature -f $feature, $($getTargetResourceResult.Features)) $result = $false } } @@ -1671,13 +1829,13 @@ function Test-TargetResource if ($PSCmdlet.ParameterSetName -eq 'ClusterInstall') { - New-VerboseMessage -Message "Clustered install, checking parameters." + Write-Verbose -Message $script:localizedData.EvaluatingClusterParameters $boundParameters.Keys | Where-Object {$_ -imatch "^FailoverCluster"} | ForEach-Object { $variableName = $_ if ($getTargetResourceResult.$variableName -ne $boundParameters[$variableName]) { - New-VerboseMessage -Message "$variableName '$($boundParameters[$variableName])' is not in the desired state for this cluster." + Write-Verbose -Message ($script:localizedData.ClusterParameterIsNotInDesiredState -f $variableName, $($boundParameters[$variableName])) $result = $false } } @@ -1698,8 +1856,8 @@ function Get-SqlMajorVersion [CmdletBinding()] param ( - [Parameter(Mandatory=$true)] - [String] + [Parameter(Mandatory = $true)] + [System.String] $Path ) @@ -1718,8 +1876,8 @@ function Get-FirstItemPropertyValue [CmdletBinding()] param ( - [Parameter(Mandatory=$true)] - [String] + [Parameter(Mandatory = $true)] + [System.String] $Path ) @@ -1738,7 +1896,7 @@ function Get-FirstItemPropertyValue <# .SYNOPSIS - Copy folder structure using RoboCopy. Every file and folder, including empty ones are copied. + Copy folder structure using Robocopy. Every file and folder, including empty ones are copied. .PARAMETER Path Source path to be copied. @@ -1746,19 +1904,19 @@ function Get-FirstItemPropertyValue .PARAMETER DestinationPath The path to the destination. #> -function Copy-ItemWithRoboCopy +function Copy-ItemWithRobocopy { [CmdletBinding()] param ( [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] - [String] + [System.String] $Path, [Parameter(Mandatory = $true)] [ValidateNotNullOrEmpty()] - [String] + [System.String] $DestinationPath ) @@ -1770,12 +1928,13 @@ function Copy-ItemWithRoboCopy if ([System.Version]$robocopyExecutable.FileVersionInfo.ProductVersion -ge [System.Version]'6.3.9600.16384') { - Write-Verbose "Robocopy is using unbuffered I/O." + Write-Verbose -Message $script:localizedData.RobocopyUsingUnbufferedIo + $robocopyArgumentUseUnbufferedIO = '/J' } else { - Write-Verbose 'Unbuffered I/O cannot be used due to incompatible version of Robocopy.' + Write-Verbose -Message $script:localizedData.RobocopyNotUsingUnbufferedIo } $robocopyArgumentList = '{0} {1} {2} {3} {4} {5}' -f $Path, @@ -1790,39 +1949,41 @@ function Copy-ItemWithRoboCopy ArgumentList = $robocopyArgumentList } - Write-Verbose ('Robocopy is started with the following arguments: {0}' -f $robocopyArgumentList ) + Write-Verbose -Message ($script:localizedData.RobocopyArguments -f $robocopyArgumentList ) $robocopyProcess = Start-Process @robocopyStartProcessParameters -Wait -NoNewWindow -PassThru switch ($($robocopyProcess.ExitCode)) { {$_ -in 8, 16} { - throw "Robocopy reported errors when copying files. Error code: $_." + $errorMessage = $script:localizedData.RobocopyErrorCopying -f $_ + New-InvalidOperationException -Message $errorMessage } {$_ -gt 7 } { - throw "Robocopy reported that failures occured when copying files. Error code: $_." + $errorMessage = $script:localizedData.RobocopyFailuresCopying -f $_ + New-InvalidResultException -Message $errorMessage } 1 { - Write-Verbose 'Robocopy copied files sucessfully' + Write-Verbose -Message $script:localizedData.RobocopySuccessful } 2 { - Write-Verbose 'Robocopy found files at the destination path that is not present at the source path, these extra files was remove at the destination path.' + Write-Verbose -Message $script:localizedData.RobocopyRemovedExtraFilesAtDestination } 3 { - Write-Verbose 'Robocopy copied files to destination sucessfully. Robocopy also found files at the destination path that is not present at the source path, these extra files was remove at the destination path.' + Write-Verbose -Message $script:localizedData.RobocopySuccessfulAndRemovedExtraFilesAtDestination } {$_ -eq 0 -or $null -eq $_ } { - Write-Verbose 'Robocopy reported that all files already present.' + Write-Verbose -Message $script:localizedData.RobocopyAllFilesPresent } } } @@ -1851,20 +2012,21 @@ function ConvertTo-Decimal { [CmdletBinding()] [OutputType([System.UInt32])] - param( + param + ( [Parameter(Mandatory = $true)] [System.Net.IPAddress] $IPAddress ) $i = 3 - $DecimalIP = 0 + $decimalIpAddress = 0 $IPAddress.GetAddressBytes() | ForEach-Object { - $DecimalIP += $_ * [Math]::Pow(256,$i) + $decimalIpAddress += $_ * [Math]::Pow(256,$i) $i-- } - return [UInt32]$DecimalIP + return [System.UInt32] $decimalIpAddress } <# @@ -1920,16 +2082,16 @@ function Test-IPAddress function Get-ServiceAccountParameters { [CmdletBinding()] - [OutputType([Hashtable])] + [OutputType([System.Collections.Hashtable])] param ( [Parameter(Mandatory = $true)] - [PSCredential] + [System.Management.Automation.PSCredential] $ServiceAccount, [Parameter(Mandatory = $true)] [ValidateSet('SQL','AGT','IS','RS','AS','FT')] - [String] + [System.String] $ServiceType ) @@ -1970,4 +2132,48 @@ function Get-ServiceAccountParameters return $parameters } +<# + .SYNOPSIS + Starts the SQL setup process- + + .PARAMETER FilePath + String containing the path to setup.exe. + + .PARAMETER ArgumentList + The arguments that should be passed to setup.exe. + + .PARAMETER Timeout + The timeout in seconds to wait for the process to finish. +#> +function Start-SqlSetupProcess +{ + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $FilePath, + + [Parameter()] + [System.String] + $ArgumentList, + + [Parameter(Mandatory = $true)] + [System.UInt32] + $Timeout + ) + + $startProcessParameters = @{ + FilePath = $FilePath + ArgumentList = $ArgumentList + } + + $sqlSetupProcess = Start-Process @startProcessParameters -PassThru -NoNewWindow -ErrorAction Stop + + Write-Verbose -Message ($script:localizedData.StartSetupProcess -f $sqlSetupProcess.Id, $startProcessParameters.FilePath, $Timeout) + + Wait-Process -InputObject $sqlSetupProcess -Timeout $Timeout -ErrorAction Stop + + return $sqlSetupProcess.ExitCode +} + Export-ModuleMember -Function *-TargetResource diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerSetup/MSFT_xSQLServerSetup.schema.mof b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlSetup/MSFT_SqlSetup.schema.mof similarity index 86% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerSetup/MSFT_xSQLServerSetup.schema.mof rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlSetup/MSFT_SqlSetup.schema.mof index f30fd5590..77f20276a 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerSetup/MSFT_xSQLServerSetup.schema.mof +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlSetup/MSFT_SqlSetup.schema.mof @@ -1,9 +1,8 @@ -[ClassVersion("1.0.0.0"), FriendlyName("xSQLServerSetup")] -class MSFT_xSQLServerSetup : OMI_BaseResource +[ClassVersion("1.0.0.0"), FriendlyName("SqlSetup")] +class MSFT_SqlSetup : OMI_BaseResource { [Write, Description("The action to be performed. Default value is 'Install'."), ValueMap{"Install","InstallFailoverCluster","AddNode","PrepareFailoverCluster","CompleteFailoverCluster"}, Values{"Install","InstallFailoverCluster","AddNode","PrepareFailoverCluster","CompleteFailoverCluster"}] String Action; [Write, Description("The path to the root of the source files for installation. I.e and UNC path to a shared resource. Environment variables can be used in the path.")] String SourcePath; - [Required, EmbeddedInstance("MSFT_Credential"), Description("Credential to be used to perform the installation.")] String SetupCredential; [Write, EmbeddedInstance("MSFT_Credential"), Description("Credentials used to access the path set in the parameter 'SourcePath'.")] String SourceCredential; [Write, Description("Suppresses reboot.")] Boolean SuppressReboot; [Write, Description("Forces reboot.")] Boolean ForceReboot; @@ -45,10 +44,12 @@ class MSFT_xSQLServerSetup : OMI_BaseResource [Write, Description("Path for Analysis Services backup files.")] String ASBackupDir; [Write, Description("Path for Analysis Services temp files.")] String ASTempDir; [Write, Description("Path for Analysis Services config.")] String ASConfigDir; + [Write, Description("The server mode for SQL Server Analysis Services instance. The default is to install in Multidimensional mode. Valid values in a cluster scenario are MULTIDIMENSIONAL or TABULAR. Parameter ASServerMode is case-sensitive. All values must be expressed in upper case."), ValueMap{"MULTIDIMENSIONAL", "TABULAR", "POWERPIVOT"}, Values{"MULTIDIMENSIONAL", "TABULAR", "POWERPIVOT"}] String ASServerMode; [Write, EmbeddedInstance("MSFT_Credential"), Description("Service account for Integration Services service.")] String ISSvcAccount; [Read, Description("Output username for the Integration Services service.")] String ISSvcAccountUsername; [Write, Description("Specifies the startup mode for SQL Server Browser service."), ValueMap{"Automatic", "Disabled", "Manual"}, Values{"Automatic", "Disabled", "Manual"}] String BrowserSvcStartupType; [Write, Description("The name of the resource group to create for the clustered SQL Server instance. Default is 'SQL Server (InstanceName)'.")] String FailoverClusterGroupName; [Write, Description("Array of IP Addresses to be assigned to the clustered SQL Server instance.")] String FailoverClusterIPAddress[]; - [Write, Description("Host name to be assigend to the clustered SQL Server instance.")] String FailoverClusterNetworkName; + [Write, Description("Host name to be assigned to the clustered SQL Server instance.")] String FailoverClusterNetworkName; + [Write, Description("The timeout, in seconds, to wait for the setup process to finish. Default value is 7200 seconds (2 hours). If the setup process does not finish before this time, and error will be thrown.")] UInt32 SetupProcessTimeout; }; diff --git a/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlSetup/en-US/MSFT_SqlSetup.strings.psd1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlSetup/en-US/MSFT_SqlSetup.strings.psd1 new file mode 100644 index 000000000..9530fcfbf --- /dev/null +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlSetup/en-US/MSFT_SqlSetup.strings.psd1 @@ -0,0 +1,77 @@ +# Localized resources for SqlSetup + +ConvertFrom-StringData @' + UsingPath = Using path '{0}'. + EvaluateReplicationFeature = Detecting replication feature ({0}). + ReplicationFeatureFound = Replication feature detected. + ReplicationFeatureNotFound = Replication feature not detected. + EvaluateDataQualityClientFeature = Detecting Data Quality Client feature ({0}). + DataQualityClientFeatureFound = Data Quality Client feature detected. + DataQualityClientFeatureNotFound = Data Quality Client feature not detected. + EvaluateDataQualityServicesFeature = Detecting Data Services Client feature ({0}). + DataQualityServicesFeatureFound = Data Quality Services feature detected. + DataQualityServicesFeatureNotFound = Data Quality Services feature not detected. + ClusterInstanceFound = Clustered instance detected. + ClusterInstanceNotFound = Clustered instance not detected. + FailoverClusterResourceFound = Clustered SQL Server resource located. + FailoverClusterResourceNotFound = Could not locate a SQL Server cluster resource for instance {0}. + EvaluateDocumentationComponentsFeature = Detecting Documentation Components feature ({0}). + DocumentationComponentsFeatureFound = Documentation Components feature detected. + DocumentationComponentsFeatureNotFound = Documentation Components feature not detected. + EvaluateDatabaseEngineFeature = Detecting Database Engine feature. + DatabaseEngineFeatureFound = Database Engine feature detected. + DatabaseEngineFeatureNotFound = Database Engine feature not detected. + EvaluateFullTextFeature = Detecting Full-text feature. + FullTextFeatureFound = Full-text feature detected. + FullTextFeatureNotFound = Full-text feature not detected. + EvaluateReportingServicesFeature = Detecting Reporting Services feature. + ReportingServicesFeatureFound = Reporting Services feature detected. + ReportingServicesFeatureNotFound = Reporting Services feature not detected. + EvaluateAnalysisServicesFeature = Detecting Analysis Services feature. + AnalysisServicesFeatureFound = Analysis Services feature detected. + AnalysisServicesFeatureNotFound = Analysis Services feature not detected. + EvaluateIntegrationServicesFeature = Detecting Integration Services feature. + IntegrationServicesFeatureFound = Integration Services feature detected. + IntegrationServicesFeatureNotFound = Integration Services feature not detected. + EvaluateClientConnectivityToolsFeature = Detecting Client Connectivity Tools feature ({0}). + ClientConnectivityToolsFeatureFound = Client Connectivity Tools feature detected. + ClientConnectivityToolsFeatureNotFound = Client Connectivity Tools feature not detected. + EvaluateClientConnectivityBackwardsCompatibilityToolsFeature = Detecting Client Connectivity Backwards Compatibility Tools feature ({0}). + ClientConnectivityBackwardsCompatibilityToolsFeatureFound = Client Connectivity Backwards Compatibility Tools feature detected. + ClientConnectivityBackwardsCompatibilityToolsFeatureNotFound = Client Connectivity Backwards Compatibility Tools feature not detected. + EvaluateClientToolsSdkFeature = Detecting Client Tools SDK feature ({0}). + ClientToolsSdkFeatureFound = Client Tools SDK feature detected. + ClientToolsSdkFeatureNotFound = Client Tools SDK feature not detected. + RobocopyIsCopying = Robocopy is copying media from source '{0}' to destination '{1}'. + FeatureNotSupported = '{0}' is not a valid value for setting 'FEATURES'. Refer to SQL Help for more information. + PathRequireClusterDriveFound = Found assigned parameter '{0}'. Adding path '{1}' to list of paths that required cluster drive. + FailoverClusterDiskMappingError = Unable to map the specified paths to valid cluster storage. Drives mapped: {0}. + FailoverClusterIPAddressNotValid = Unable to map the specified IP Address(es) to valid cluster networks. + AddingFirstSystemAdministratorSqlServer = Adding user '{0}' from the parameter 'PsDscRunAsCredential' as the first system administrator account for SQL Server. + AddingFirstSystemAdministratorAnalysisServices = Adding user '{0}' from the parameter 'PsDscRunAsCredential' as the first system administrator account for Analysis Services. + SetupArguments = Starting setup using arguments: {0} + SetupExitMessage = Setup exited with code '{0}'. + SetupSuccessful = Setup finished successfully. + SetupSuccessfulRebootRequired = Setup finished successfully, but a reboot is required. + SetupFailed = Please see the 'Summary.txt' log file in the 'Setup Bootstrap\\Log' folder. + Reboot = Rebooting target node. + SuppressReboot = Suppressing reboot of target node. + TestFailedAfterSet = Test-TargetResource returned false after calling Set-TargetResource. + FeaturesFound = Features found: {0} + UnableToFindFeature = Unable to find feature '{0}' among the installed features: '{1}'. + EvaluatingClusterParameters = Clustered install, checking parameters. + ClusterParameterIsNotInDesiredState = {0} '{1}' is not in the desired state for this cluster. + RobocopyUsingUnbufferedIo = Robocopy is using unbuffered I/O. + RobocopyNotUsingUnbufferedIo = Unbuffered I/O cannot be used due to incompatible version of Robocopy. + RobocopyArguments = Robocopy is started with the following arguments: {0} + RobocopyErrorCopying = Robocopy reported errors when copying files. Error code: {0}. + RobocopyFailuresCopying = Robocopy reported that failures occurred when copying files. Error code: {0}. + RobocopySuccessful = Robocopy copied files successfully + RobocopyRemovedExtraFilesAtDestination = Robocopy found files at the destination path that is not present at the source path, these extra files was remove at the destination path. + RobocopySuccessfulAndRemovedExtraFilesAtDestination = Robocopy copied files to destination successfully. Robocopy also found files at the destination path that is not present at the source path, these extra files was remove at the destination path. + RobocopyAllFilesPresent = Robocopy reported that all files already present. + StartSetupProcess = Started the process with id {0} using the path '{1}', and with a timeout value of {2} seconds. + EvaluateMasterDataServicesFeature = Detecting Master Data Services (MDS) feature ({0}). + MasterDataServicesFeatureFound = 'Master Data Services (MDS) feature detected.' + MasterDataServicesFeatureNotFound = 'Master Data Services (MDS) feature not detected.' +'@ diff --git a/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlSetup/sv-SE/MSFT_SqlSetup.strings.psd1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlSetup/sv-SE/MSFT_SqlSetup.strings.psd1 new file mode 100644 index 000000000..ed61272c7 --- /dev/null +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlSetup/sv-SE/MSFT_SqlSetup.strings.psd1 @@ -0,0 +1,77 @@ +# Swedish localized resources for SqlSetup + +ConvertFrom-StringData @' + UsingPath = Använder sökväg '{0}'. + EvaluateReplicationFeature = Letar efter funktionen Replication ({0}). + ReplicationFeatureFound = Replication funktionen hittad. + ReplicationFeatureNotFound = Replication funktionen hittades inte. + EvaluateDataQualityClientFeature = Letar efter Data Quality Client funktionen ({0}). + DataQualityClientFeatureFound = Data Quality Client funktionen hittad. + DataQualityClientFeatureNotFound = Data Quality Client funktionen hittades inte. + EvaluateDataQualityServicesFeature = Letar efter Data Services Client funktionen ({0}). + DataQualityServicesFeatureFound = Data Quality Services funktionen hittad. + DataQualityServicesFeatureNotFound = Data Quality Services funktionen hittades inte. + ClusterInstanceFound = Klustrad instans hittad. + ClusterInstanceNotFound = Klustrad instans hittades inte. + FailoverClusterResourceFound = En SQL Server klusterresurs hittad. + FailoverClusterResourceNotFound = Kunde inte hitta en SQL Server klusteresurs för instans {0}. + EvaluateDocumentationComponentsFeature = Letar efter Documentation Components funktionen ({0}). + DocumentationComponentsFeatureFound = Documentation Components funktionen hittad. + DocumentationComponentsFeatureNotFound = Documentation Components funktionen hittades inte. + EvaluateDatabaseEngineFeature = Letar efter Database Engine funktionen. + DatabaseEngineFeatureFound = Database Engine funktionen hittad. + DatabaseEngineFeatureNotFound = Database Engine funktionen hittades inte. + EvaluateFullTextFeature = Letar efter Full-text funktionen. + FullTextFeatureFound = Full-text funktionen hittad. + FullTextFeatureNotFound = Full-text funktionen hittades inte. + EvaluateReportingServicesFeature = Letar efter Reporting Services funktionen. + ReportingServicesFeatureFound = Reporting Services funktionen hittad. + ReportingServicesFeatureNotFound = Reporting Services funktionen hittades inte. + EvaluateAnalysisServicesFeature = Letar efter Analysis Services funktionen. + AnalysisServicesFeatureFound = Analysis Services funktionen hittad. + AnalysisServicesFeatureNotFound = Analysis Services funktionen hittades inte. + EvaluateIntegrationServicesFeature = Letar efter Integration Services funktionen. + IntegrationServicesFeatureFound = Integration Services funktionen hittad. + IntegrationServicesFeatureNotFound = Integration Services funktionen hittades inte. + EvaluateClientConnectivityToolsFeature = Letar efter Client Connectivity Tools funktionen ({0}). + ClientConnectivityToolsFeatureFound = Client Connectivity Tools funktionen hittad. + ClientConnectivityToolsFeatureNotFound = Client Connectivity Tools funktionen hittades inte. + EvaluateClientConnectivityBackwardsCompatibilityToolsFeature = Letar efter Client Connectivity Backwards Compatibility Tools funktionen ({0}). + ClientConnectivityBackwardsCompatibilityToolsFeatureFound = Client Connectivity Backwards Compatibility Tools funktionen hittad. + ClientConnectivityBackwardsCompatibilityToolsFeatureNotFound = Client Connectivity Backwards Compatibility Tools funktionen hittades inte. + EvaluateClientToolsSdkFeature = Letar efter Client Tools SDK funktionen ({0}). + ClientToolsSdkFeatureFound = Client Tools SDK funktionen hittad. + ClientToolsSdkFeatureNotFound = Client Tools SDK funktionen hittades inte. + RobocopyIsCopying = Robocopy kopierar media från källan '{0}' till destinationen '{1}'. + FeatureNotSupported = '{0}' är inte ett giltigt värde för egenskapen 'FEATURES'. Titta i hjälpdokumentationen för SQL Server för mer information. + PathRequireClusterDriveFound = Hittade tilldelad parameter '{0}'. Adderar sökväg '{1}' till listan av sökvägar som kräver en klustrad enhet. + FailoverClusterDiskMappingError = Kunde inte koppla den specifika sökvägen till en giltig klusterlagring. Enheter kopplade: {0}. + FailoverClusterIPAddressNotValid = Kunde inte koppla den specifika IP-adressen, eller IP-adresser, till ett giltigt klusternätverk. + AddingFirstSystemAdministratorSqlServer = Adderar användaren '{0}' från parametern 'PsDscRunAsCredential' som det första systemadminstratörskontot för SQL Server. + AddingFirstSystemAdministratorAnalysisServices = Adderar användaren '{0}' från parametern 'PsDscRunAsCredential' som det första systemadminstratörskontot för Analysis Services. + SetupArguments = Startar installationen med följande argument: {0} + SetupExitMessage = Installationen avslutades med felkod '{0}'. + SetupSuccessful = Installationen lyckades. + SetupSuccessfulRebootRequired = Installationen lyckades, men en omstart krävs. + SetupFailed = Vänligen titta i loggfilen 'Summary.txt' i sökvägen 'Setup Bootstrap\\Log'. + Reboot = Startar om målnod. + SuppressReboot = Förhindrar omstart av målnod. + TestFailedAfterSet = Test-TargetResource retunerade falskt efter anropet till Set-TargetResource. + FeaturesFound = Funktioner funna: {0} + UnableToFindFeature = Kunde inte hitta funktion '{0}' bland som installerade funktionerna: '{1}'. + EvaluatingClusterParameters = Klustrad installation, kontrollerar parametrar. + ClusterParameterIsNotInDesiredState = {0} '{1}' är inte i önskat läge för detta kluster. + RobocopyUsingUnbufferedIo = Robocopy använder sig av obuffrad I/O. + RobocopyNotUsingUnbufferedIo = Obuffrad I/O kan inte användas på grund av versionen av Robocopy inte är kompatibel. + RobocopyArguments = Robocopy startas med följande argument: {0} + RobocopyErrorCopying = Robocopy rapporterade fel när filer kopierades. Felkod: {0}. + RobocopyFailuresCopying = Robocopy rapporterade att fel uppstod när filer kopierades. Felkod: {0}. + RobocopySuccessful = Robocopy lyckades kopiera filer till destinationen. + RobocopyRemovedExtraFilesAtDestination = Robocopy fann extra filer på destinationen som inte finns i källan, dessa extra filer togs bort på destinationen. + RobocopySuccessfulAndRemovedExtraFilesAtDestination = Robocopy lyckades kopiera filer till destinationen. Robocopy fann extra filer på destinationen som inte finns i källan, dessa extra filer togs bort på destinationen. + RobocopyAllFilesPresent = Robocopy rapporterade att alla filer redan finns på destinationen. + StartSetupProcess = Startade processen med id {0}, använder sig av sökvägen '{1}', och med en tidsgräns på {2} sekunder. + EvaluateMasterDataServicesFeature = Letar efter Master Data Services (MDS) funktion ({0}). + MasterDataServicesFeatureFound = Master Data Services (MDS) funktionen hittad. + MasterDataServicesFeatureNotFound = Master Data Services (MDS) funktionen hittades inte. +'@ diff --git a/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlWaitForAG/MSFT_SqlWaitForAG.psm1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlWaitForAG/MSFT_SqlWaitForAG.psm1 new file mode 100644 index 000000000..253dd405e --- /dev/null +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlWaitForAG/MSFT_SqlWaitForAG.psm1 @@ -0,0 +1,175 @@ +Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) ` + -ChildPath 'SqlServerDscHelper.psm1') ` + -Force + +<# + .SYNOPSIS + Returns the cluster role/group that is waiting to be created, + along with the time and number of times to wait. + + .PARAMETER Name + Name of the cluster role/group to look for (normally the same as the Availability Group name). + + .PARAMETER RetryIntervalSec + The interval, in seconds, to check for the presence of the cluster role/group. + Default value is 20 seconds. + When the cluster role/group has been found the resource will wait for this amount of time once + more before returning. + + .PARAMETER RetryCount + Maximum number of retries until the resource will timeout and throw an error. Default values is 30 times. +#> +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $Name, + + [Parameter()] + [System.UInt64] + $RetryIntervalSec = 20, + + [Parameter()] + [System.UInt32] + $RetryCount = 30 + ) + + $clusterGroupFound = $false + + $clusterGroup = Get-ClusterGroup -Name $Name -ErrorAction SilentlyContinue + if ($null -ne $clusterGroup) + { + $clusterGroupFound = $true + } + + return @{ + Name = $Name + RetryIntervalSec = $RetryIntervalSec + RetryCount = $RetryCount + GroupExist = $clusterGroupFound + } +} + +<# + .SYNOPSIS + Waits for a cluster role/group to be created + + .PARAMETER Name + Name of the cluster role/group to look for (normally the same as the Availability Group name). + + .PARAMETER RetryIntervalSec + The interval, in seconds, to check for the presence of the cluster role/group. + Default value is 20 seconds. + When the cluster role/group has been found the resource will wait for this amount of time once + more before returning. + + .PARAMETER RetryCount + Maximum number of retries until the resource will timeout and throw an error. Default values is 30 times. +#> +function Set-TargetResource +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $Name, + + [Parameter()] + [System.UInt64] + $RetryIntervalSec = 20, + + [Parameter()] + [System.UInt32] + $RetryCount = 30 + ) + + New-VerboseMessage -Message "Checking for cluster group $Name. Will try for a total of $($RetryIntervalSec*$RetryCount) seconds." + + $getTargetResourceParameters = @{ + Name = $Name + RetryIntervalSec = $RetryIntervalSec + RetryCount = $RetryCount + } + + for ($forLoopCount = 0; $forLoopCount -lt $RetryCount; $forLoopCount++) + { + $clusterGroupFound = (Get-TargetResource @getTargetResourceParameters).GroupExist + if ($clusterGroupFound) + { + New-VerboseMessage -Message "Found cluster group $Name. Will sleep for another $RetryIntervalSec seconds before continuing." + Start-Sleep -Seconds $RetryIntervalSec + break + } + + New-VerboseMessage -Message "Cluster group $Name not found. Will retry again after $RetryIntervalSec sec" + Start-Sleep -Seconds $RetryIntervalSec + } + + if (-not $clusterGroupFound) + { + throw "Cluster group $Name not found after $RetryCount attempts with $RetryIntervalSec sec interval" + } +} + +<# + .SYNOPSIS + Tests if the cluster role/group has been created. + + .PARAMETER Name + Name of the cluster role/group to look for (normally the same as the Availability Group name). + + .PARAMETER RetryIntervalSec + The interval, in seconds, to check for the presence of the cluster role/group. + Default value is 20 seconds. + When the cluster role/group has been found the resource will wait for this amount of time once + more before returning. + + .PARAMETER RetryCount + Maximum number of retries until the resource will timeout and throw an error. Default values is 30 times. +#> +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $Name, + + [Parameter()] + [System.UInt64] + $RetryIntervalSec = 20, + + [Parameter()] + [System.UInt32] + $RetryCount = 30 + ) + + New-VerboseMessage -Message "Testing for cluster group $Name." + + $getTargetResourceParameters = @{ + Name = $Name + RetryIntervalSec = $RetryIntervalSec + RetryCount = $RetryCount + } + + $clusterGroupFound = (Get-TargetResource @getTargetResourceParameters).GroupExist + if ($clusterGroupFound) + { + New-VerboseMessage -Message "Found cluster group $Name" + } + else + { + New-VerboseMessage -Message "Cluster group $Name not found" + } + + return $clusterGroupFound +} + +Export-ModuleMember -Function *-TargetResource diff --git a/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlWaitForAG/MSFT_SqlWaitForAG.schema.mof b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlWaitForAG/MSFT_SqlWaitForAG.schema.mof new file mode 100644 index 000000000..3b40b08fb --- /dev/null +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlWaitForAG/MSFT_SqlWaitForAG.schema.mof @@ -0,0 +1,8 @@ +[ClassVersion("1.0.0.0"), FriendlyName("SqlWaitForAG")] +class MSFT_SqlWaitForAG : OMI_BaseResource +{ + [Key, Description("Name of the cluster role/group to look for (normally the same as the Availability Group name).")] String Name; + [Write, Description("The interval, in seconds, to check for the presence of the cluster role/group. Default value is 20 seconds. When the cluster role/group has been found the resource will wait for this amount of time once more before returning.")] UInt64 RetryIntervalSec; + [Write, Description("Maximum number of retries until the resource will timeout and throw an error. Default values is 30 times.")] UInt32 RetryCount; + [Read, Description("Returns $true if the cluster role/group exist, otherwise it returns $false. Used by Get-TargetResource.")] Boolean GroupExist; +}; diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerFirewall/MSFT_xSQLServerFirewall.psm1 b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlWindowsFirewall/MSFT_SqlWindowsFirewall.psm1 similarity index 77% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerFirewall/MSFT_xSQLServerFirewall.psm1 rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlWindowsFirewall/MSFT_SqlWindowsFirewall.psm1 index c7b6f20d5..40ac00119 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerFirewall/MSFT_xSQLServerFirewall.psm1 +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlWindowsFirewall/MSFT_SqlWindowsFirewall.psm1 @@ -1,5 +1,5 @@ $script:currentPath = Split-Path -Path $MyInvocation.MyCommand.Path -Parent -Import-Module -Name (Join-Path -Path (Split-Path -Path (Split-Path -Path $script:currentPath -Parent) -Parent) -ChildPath 'xSQLServerHelper.psm1') +Import-Module -Name (Join-Path -Path (Split-Path -Path (Split-Path -Path $script:currentPath -Parent) -Parent) -ChildPath 'SqlServerDscHelper.psm1') <# .SYNOPSIS @@ -9,7 +9,7 @@ Import-Module -Name (Join-Path -Path (Split-Path -Path (Split-Path -Path $script The path to the root of the source files for installation. I.e and UNC path to a shared resource. Environment variables can be used in the path. .PARAMETER Features - One or more SQL feature to create default firewall rules for. Each feature should be seperated with a comma, i.e. 'SQLEngine,IS,RS'. + One or more SQL feature to create default firewall rules for. Each feature should be separated with a comma, i.e. 'SQLEngine,IS,RS'. .PARAMETER SourceCredential Credentials used to access the path set in the parameter `SourcePath`. @@ -48,8 +48,8 @@ function Get-TargetResource { $newSmbMappingParameters = @{ RemotePath = $SourcePath - UserName = "$($SourceCredential.GetNetworkCredential().Domain)\$($SourceCredential.GetNetworkCredential().UserName)" - Password = $($SourceCredential.GetNetworkCredential().Password) + UserName = "$($SourceCredential.GetNetworkCredential().Domain)\$($SourceCredential.GetNetworkCredential().UserName)" + Password = $($SourceCredential.GetNetworkCredential().Password) } $null = New-SmbMapping @newSmbMappingParameters @@ -66,7 +66,7 @@ function Get-TargetResource Remove-SmbMapping -RemotePath $SourcePath -Force } - if($InstanceName -eq 'MSSQLSERVER') + if ($InstanceName -eq 'MSSQLSERVER') { $databaseServiceName = 'MSSQLSERVER' $reportServiceName = 'ReportServer' @@ -102,10 +102,10 @@ function Get-TargetResource $databaseEngineFirewallRuleParameters = @{ DisplayName = $databaseEngineFirewallRuleDisplayName - Program = $pathToDatabaseEngineExecutable - Enabled = 'True' - Profile = 'Any' - Direction = 'Inbound' + Program = $pathToDatabaseEngineExecutable + Enabled = 'True' + Profile = 'Any' + Direction = 'Inbound' } if (Test-IsFirewallRuleInDesiredState @databaseEngineFirewallRuleParameters) @@ -121,10 +121,10 @@ function Get-TargetResource $browserFirewallRuleParameters = @{ DisplayName = $browserFirewallRuleDisplayName - Service = $browserServiceName - Enabled = 'True' - Profile = 'Any' - Direction = 'Inbound' + Service = $browserServiceName + Enabled = 'True' + Profile = 'Any' + Direction = 'Inbound' } if (Test-IsFirewallRuleInDesiredState @browserFirewallRuleParameters) @@ -150,11 +150,11 @@ function Get-TargetResource $reportingServicesNoSslFirewallRuleParameters = @{ DisplayName = $reportingServicesNoSslFirewallRuleDisplayName - Protocol = $reportingServicesNoSslProtocol - LocalPort = $reportingServicesNoSslLocalPort - Enabled = 'True' - Profile = 'Any' - Direction = 'Inbound' + Protocol = $reportingServicesNoSslProtocol + LocalPort = $reportingServicesNoSslLocalPort + Enabled = 'True' + Profile = 'Any' + Direction = 'Inbound' } $reportingServicesSslProtocol = 'TCP' @@ -163,15 +163,15 @@ function Get-TargetResource $reportingServicesSslFirewallRuleParameters = @{ DisplayName = $reportingServicesSslFirewallRuleDisplayName - Protocol = $reportingServicesSslProtocol - LocalPort = $reportingServicesSslLocalPort - Enabled = 'True' - Profile = 'Any' - Direction = 'Inbound' + Protocol = $reportingServicesSslProtocol + LocalPort = $reportingServicesSslLocalPort + Enabled = 'True' + Profile = 'Any' + Direction = 'Inbound' } if ((Test-IsFirewallRuleInDesiredState @reportingServicesNoSslFirewallRuleParameters) ` - -and (Test-IsFirewallRuleInDesiredState @reportingServicesSslFirewallRuleParameters)) + -and (Test-IsFirewallRuleInDesiredState @reportingServicesSslFirewallRuleParameters)) { $reportingServicesFirewall = $true } @@ -192,10 +192,10 @@ function Get-TargetResource $analysisServicesFirewallRuleParameters = @{ DisplayName = $analysisServicesFirewallRuleDisplayName - Service = $analysisServiceName - Enabled = 'True' - Profile = 'Any' - Direction = 'Inbound' + Service = $analysisServiceName + Enabled = 'True' + Profile = 'Any' + Direction = 'Inbound' } if (Test-IsFirewallRuleInDesiredState @analysisServicesFirewallRuleParameters) @@ -211,10 +211,10 @@ function Get-TargetResource $browserFirewallRuleParameters = @{ DisplayName = $browserFirewallRuleDisplayName - Service = $browserServiceName - Enabled = 'True' - Profile = 'Any' - Direction = 'Inbound' + Service = $browserServiceName + Enabled = 'True' + Profile = 'Any' + Direction = 'Inbound' } if (Test-IsFirewallRuleInDesiredState @browserFirewallRuleParameters) @@ -239,10 +239,10 @@ function Get-TargetResource $integrationServicesFirewallRuleApplicationParameters = @{ DisplayName = $integrationServicesRuleApplicationDisplayName - Program = $pathToIntegrationServicesExecutable - Enabled = 'True' - Profile = 'Any' - Direction = 'Inbound' + Program = $pathToIntegrationServicesExecutable + Enabled = 'True' + Profile = 'Any' + Direction = 'Inbound' } $integrationServicesProtocol = 'TCP' @@ -251,15 +251,15 @@ function Get-TargetResource $integrationServicesFirewallRulePortParameters = @{ DisplayName = $integrationServicesFirewallRuleDisplayName - Protocol = $integrationServicesProtocol - LocalPort = $integrationServicesLocalPort - Enabled = 'True' - Profile = 'Any' - Direction = 'Inbound' + Protocol = $integrationServicesProtocol + LocalPort = $integrationServicesLocalPort + Enabled = 'True' + Profile = 'Any' + Direction = 'Inbound' } if ((Test-IsFirewallRuleInDesiredState @integrationServicesFirewallRuleApplicationParameters) ` - -and (Test-IsFirewallRuleInDesiredState @integrationServicesFirewallRulePortParameters)) + -and (Test-IsFirewallRuleInDesiredState @integrationServicesFirewallRulePortParameters)) { $integrationServicesFirewall = $true } @@ -274,9 +274,9 @@ function Get-TargetResource if ( ($Features -match 'SQLENGINE' -and -not ($databaseEngineFirewall -and $browserFirewall)) ` - -or ($Features -match 'RS' -and -not $reportingServicesFirewall) ` - -or ($Features -match 'AS' -and -not ($analysisServicesFirewall -and $browserFirewall)) ` - -or ($Features -match 'IS' -and -not $integrationServicesFirewall) + -or ($Features -match 'RS' -and -not $reportingServicesFirewall) ` + -or ($Features -match 'AS' -and -not ($analysisServicesFirewall -and $browserFirewall)) ` + -or ($Features -match 'IS' -and -not $integrationServicesFirewall) ) { $ensure = 'Absent' @@ -286,14 +286,14 @@ function Get-TargetResource $featuresInstalled = $featuresInstalled.Trim(',') return @{ - Ensure = $ensure - SourcePath = $SourcePath - Features = $featuresInstalled - InstanceName = $InstanceName - DatabaseEngineFirewall = $databaseEngineFirewall - BrowserFirewall = $browserFirewall - ReportingServicesFirewall = $reportingServicesFirewall - AnalysisServicesFirewall = $analysisServicesFirewall + Ensure = $ensure + SourcePath = $SourcePath + Features = $featuresInstalled + InstanceName = $InstanceName + DatabaseEngineFirewall = $databaseEngineFirewall + BrowserFirewall = $browserFirewall + ReportingServicesFirewall = $reportingServicesFirewall + AnalysisServicesFirewall = $analysisServicesFirewall IntegrationServicesFirewall = $integrationServicesFirewall } } @@ -309,7 +309,7 @@ function Get-TargetResource The path to the root of the source files for installation. I.e and UNC path to a shared resource. Environment variables can be used in the path. .PARAMETER Features - One or more SQL feature to create default firewall rules for. Each feature should be seperated with a comma, i.e. 'SQLEngine,IS,RS'. + One or more SQL feature to create default firewall rules for. Each feature should be separated with a comma, i.e. 'SQLEngine,IS,RS'. .PARAMETER SourceCredential Credentials used to access the path set in the parameter `SourcePath`. @@ -323,7 +323,7 @@ function Set-TargetResource param ( [Parameter()] - [ValidateSet('Present','Absent')] + [ValidateSet('Present', 'Absent')] [System.String] $Ensure = 'Present', @@ -352,8 +352,8 @@ function Set-TargetResource { $newSmbMappingParameters = @{ RemotePath = $SourcePath - UserName = "$($SourceCredential.GetNetworkCredential().Domain)\$($SourceCredential.GetNetworkCredential().UserName)" - Password = $($SourceCredential.GetNetworkCredential().Password) + UserName = "$($SourceCredential.GetNetworkCredential().Domain)\$($SourceCredential.GetNetworkCredential().UserName)" + Password = $($SourceCredential.GetNetworkCredential().Password) } $null = New-SmbMapping @newSmbMappingParameters @@ -396,10 +396,10 @@ function Set-TargetResource $databaseEngineFirewallRuleParameters = @{ DisplayName = $databaseEngineFirewallRuleDisplayName - Program = $pathToDatabaseEngineExecutable - Enabled = 'True' - Profile = 'Any' - Direction = 'Inbound' + Program = $pathToDatabaseEngineExecutable + Enabled = 'True' + Profile = 'Any' + Direction = 'Inbound' } if (-not (Test-IsFirewallRuleInDesiredState @databaseEngineFirewallRuleParameters)) @@ -414,10 +414,10 @@ function Set-TargetResource $browserFirewallRuleParameters = @{ DisplayName = $browserFirewallRuleDisplayName - Service = $browserServiceName - Enabled = 'True' - Profile = 'Any' - Direction = 'Inbound' + Service = $browserServiceName + Enabled = 'True' + Profile = 'Any' + Direction = 'Inbound' } if (-not (Test-IsFirewallRuleInDesiredState @browserFirewallRuleParameters)) @@ -437,11 +437,11 @@ function Set-TargetResource $reportingServicesNoSslFirewallRuleParameters = @{ DisplayName = $reportingServicesNoSslFirewallRuleDisplayName - Protocol = $reportingServicesNoSslProtocol - LocalPort = $reportingServicesNoSslLocalPort - Enabled = 'True' - Profile = 'Any' - Direction = 'Inbound' + Protocol = $reportingServicesNoSslProtocol + LocalPort = $reportingServicesNoSslLocalPort + Enabled = 'True' + Profile = 'Any' + Direction = 'Inbound' } if (-not (Test-IsFirewallRuleInDesiredState @reportingServicesNoSslFirewallRuleParameters)) @@ -455,11 +455,11 @@ function Set-TargetResource $reportingServicesSslFirewallRuleParameters = @{ DisplayName = $reportingServicesSslFirewallRuleDisplayName - Protocol = $reportingServicesSslProtocol - LocalPort = $reportingServicesSslLocalPort - Enabled = 'True' - Profile = 'Any' - Direction = 'Inbound' + Protocol = $reportingServicesSslProtocol + LocalPort = $reportingServicesSslLocalPort + Enabled = 'True' + Profile = 'Any' + Direction = 'Inbound' } if (-not (Test-IsFirewallRuleInDesiredState @reportingServicesSslFirewallRuleParameters)) @@ -477,13 +477,13 @@ function Set-TargetResource $analysisServicesFirewallRuleParameters = @{ DisplayName = $analysisServicesFirewallRuleDisplayName - Service = $analysisServiceName - Enabled = 'True' - Profile = 'Any' - Direction = 'Inbound' + Service = $analysisServiceName + Enabled = 'True' + Profile = 'Any' + Direction = 'Inbound' } - if(-not (Test-IsFirewallRuleInDesiredState @analysisServicesFirewallRuleParameters)) + if (-not (Test-IsFirewallRuleInDesiredState @analysisServicesFirewallRuleParameters)) { New-NetFirewallRule @analysisServicesFirewallRuleParameters } @@ -495,10 +495,10 @@ function Set-TargetResource $browserFirewallRuleParameters = @{ DisplayName = $browserFirewallRuleDisplayName - Service = $browserServiceName - Enabled = 'True' - Profile = 'Any' - Direction = 'Inbound' + Service = $browserServiceName + Enabled = 'True' + Profile = 'Any' + Direction = 'Inbound' } if (-not (Test-IsFirewallRuleInDesiredState @browserFirewallRuleParameters)) @@ -517,10 +517,10 @@ function Set-TargetResource $integrationServicesFirewallRuleApplicationParameters = @{ DisplayName = $integrationServicesRuleApplicationDisplayName - Program = $pathToIntegrationServicesExecutable - Enabled = 'True' - Profile = 'Any' - Direction = 'Inbound' + Program = $pathToIntegrationServicesExecutable + Enabled = 'True' + Profile = 'Any' + Direction = 'Inbound' } if (-not (Test-IsFirewallRuleInDesiredState @integrationServicesFirewallRuleApplicationParameters)) @@ -534,11 +534,11 @@ function Set-TargetResource $integrationServicesFirewallRulePortParameters = @{ DisplayName = $integrationServicesFirewallRuleDisplayName - Protocol = $integrationServicesProtocol - LocalPort = $integrationServicesLocalPort - Enabled = 'True' - Profile = 'Any' - Direction = 'Inbound' + Protocol = $integrationServicesProtocol + LocalPort = $integrationServicesLocalPort + Enabled = 'True' + Profile = 'Any' + Direction = 'Inbound' } if (-not (Test-IsFirewallRuleInDesiredState @integrationServicesFirewallRulePortParameters)) @@ -567,7 +567,7 @@ function Set-TargetResource The path to the root of the source files for installation. I.e and UNC path to a shared resource. Environment variables can be used in the path. .PARAMETER Features - One or more SQL feature to create default firewall rules for. Each feature should be seperated with a comma, i.e. 'SQLEngine,IS,RS'. + One or more SQL feature to create default firewall rules for. Each feature should be separated with a comma, i.e. 'SQLEngine,IS,RS'. .PARAMETER SourceCredential Credentials used to access the path set in the parameter `SourcePath`. @@ -582,7 +582,7 @@ function Test-TargetResource param ( [Parameter()] - [ValidateSet('Present','Absent')] + [ValidateSet('Present', 'Absent')] [System.String] $Ensure = 'Present', @@ -610,7 +610,7 @@ function Test-TargetResource <# .SYNOPSIS - Get the path to SQL Server executables. + Get the path to SQL Server executable. .PARAMETER Feature String containing the feature name for which to get the path. @@ -627,16 +627,16 @@ function Get-SQLPath [CmdletBinding()] param ( - [Parameter(Mandatory=$true)] - [String] + [Parameter(Mandatory = $true)] + [System.String] $Feature, [Parameter()] - [String] + [System.String] $InstanceName, [Parameter()] - [String] + [System.String] $SQLVersion ) @@ -646,16 +646,16 @@ function Get-SQLPath { 'SQLENGINE' { - $productinstanceId = 'SQL' + $productInstanceId = 'SQL' } 'AS' { - $productinstanceId = 'OLAP' + $productInstanceId = 'OLAP' } } - $instanceId = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\$($productinstanceId)" -Name $InstanceName).$InstanceName + $instanceId = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\$($productInstanceId)" -Name $InstanceName).$InstanceName $path = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$($instanceId)\setup" -Name 'SQLBinRoot').SQLBinRoot } @@ -684,7 +684,7 @@ function Get-SQLPath String containing the direction of traffic for the the firewall rule. It can be either 'Inbound' or 'Outbound'. .PARAMETER Program - String containing the path to an executable. This paramater is optional. + String containing the path to an executable. This parameter is optional. .PARAMETER Service String containing the name of a service for the firewall rule. This parameter is optional. @@ -702,40 +702,40 @@ function Test-IsFirewallRuleInDesiredState [CmdletBinding()] param ( - [Parameter(Mandatory=$true)] - [String] + [Parameter(Mandatory = $true)] + [System.String] $DisplayName, - [Parameter(Mandatory=$true)] - [ValidateSet('True','False')] - [String] + [Parameter(Mandatory = $true)] + [ValidateSet('True', 'False')] + [System.String] $Enabled, - [Parameter(Mandatory=$true)] - [String[]] - [ValidateSet('Any','Domain','Private','Public','NotApplicable')] + [Parameter(Mandatory = $true)] + [System.String[]] + [ValidateSet('Any', 'Domain', 'Private', 'Public', 'NotApplicable')] $Profile, - [Parameter(Mandatory=$true)] - [ValidateSet('Inbound','Outbound')] - [String] + [Parameter(Mandatory = $true)] + [ValidateSet('Inbound', 'Outbound')] + [System.String] $Direction, [Parameter()] - [String] + [System.String] $Program, [Parameter()] - [String] + [System.String] $Service, [Parameter()] - [ValidateSet('TCP','UDP','ICMPv4','ICMPv6')] - [String] + [ValidateSet('TCP', 'UDP', 'ICMPv4', 'ICMPv6')] + [System.String] $Protocol, [Parameter()] - [String] + [System.String] $LocalPort ) @@ -795,8 +795,8 @@ function Get-SqlMajorVersion [CmdletBinding()] param ( - [Parameter(Mandatory=$true)] - [String] + [Parameter(Mandatory = $true)] + [System.String] $path ) diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerFirewall/MSFT_xSQLServerFirewall.schema.mof b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlWindowsFirewall/MSFT_SqlWindowsFirewall.schema.mof similarity index 74% rename from lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerFirewall/MSFT_xSQLServerFirewall.schema.mof rename to lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlWindowsFirewall/MSFT_SqlWindowsFirewall.schema.mof index 8879b0459..11021c58d 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerFirewall/MSFT_xSQLServerFirewall.schema.mof +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/DSCResources/MSFT_SqlWindowsFirewall/MSFT_SqlWindowsFirewall.schema.mof @@ -1,14 +1,14 @@ -[ClassVersion("1.0.0.0"), FriendlyName("xSQLServerFirewall")] -class MSFT_xSQLServerFirewall : OMI_BaseResource +[ClassVersion("1.0.0.0"), FriendlyName("SqlWindowsFirewall")] +class MSFT_SqlWindowsFirewall : OMI_BaseResource { [Write, Description("An enumerated value that describes if the SQL firewall rules are is expected to be enabled on the machine.\nPresent {default} \nAbsent \n"), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; [Write, Description("UNC path to the root of the source files for installation.")] String SourcePath; [Key, Description("SQL features to enable firewall rules for.")] String Features; [Key, Description("SQL instance to enable firewall rules for.")] String InstanceName; - [Read, Description("Is the firewall rule for the Database Engine enabled?")] boolean DatabaseEngineFirewall; - [Read, Description("Is the firewall rule for the Browser enabled?")] boolean BrowserFirewall; - [Read, Description("Is the firewall rule for Reporting Services enabled?")] boolean ReportingServicesFirewall; - [Read, Description("Is the firewall rule for Analysis Services enabled?")] boolean AnalysisServicesFirewall; - [Read, Description("Is the firewall rule for the Integration Services enabled?")] boolean IntegrationServicesFirewall; + [Read, Description("Is the firewall rule for the Database Engine enabled?")] Boolean DatabaseEngineFirewall; + [Read, Description("Is the firewall rule for the Browser enabled?")] Boolean BrowserFirewall; + [Read, Description("Is the firewall rule for Reporting Services enabled?")] Boolean ReportingServicesFirewall; + [Read, Description("Is the firewall rule for Analysis Services enabled?")] Boolean AnalysisServicesFirewall; + [Read, Description("Is the firewall rule for the Integration Services enabled?")] Boolean IntegrationServicesFirewall; [Write, EmbeddedInstance("MSFT_Credential"), Description("Credentials used to access the path set in the parameter 'SourcePath'.")] String SourceCredential; }; diff --git a/lib/puppet_x/dsc_resources/xSQLServer/LICENSE b/lib/puppet_x/dsc_resources/SqlServerDsc/LICENSE similarity index 94% rename from lib/puppet_x/dsc_resources/xSQLServer/LICENSE rename to lib/puppet_x/dsc_resources/SqlServerDsc/LICENSE index 567fd6a52..6bf8d3abb 100644 --- a/lib/puppet_x/dsc_resources/xSQLServer/LICENSE +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/LICENSE @@ -1,6 +1,6 @@ The MIT License (MIT) -Copyright (c) 2015 Microsoft Corporation. +Copyright (c) 2018 Microsoft Corporation. Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal @@ -18,4 +18,4 @@ 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. \ No newline at end of file +THE SOFTWARE. diff --git a/lib/puppet_x/dsc_resources/SqlServerDsc/SQLServerDsc.psd1 b/lib/puppet_x/dsc_resources/SqlServerDsc/SQLServerDsc.psd1 new file mode 100644 index 000000000..eb740c274 --- /dev/null +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/SQLServerDsc.psd1 @@ -0,0 +1,233 @@ +@{ + # Version number of this module. + ModuleVersion = '11.0.0.0' + + # ID used to uniquely identify this module + GUID = '693ee082-ed36-45a7-b490-88b07c86b42f' + + # Author of this module + Author = 'Microsoft Corporation' + + # Company or vendor of this module + CompanyName = 'Microsoft Corporation' + + # Copyright statement for this module + Copyright = '(c) 2018 Microsoft Corporation. All rights reserved.' + + # Description of the functionality provided by this module + Description = 'Module with DSC Resources for deployment and configuration of Microsoft SQL Server.' + + # Minimum version of the Windows PowerShell engine required by this module + PowerShellVersion = '5.0' + + # Minimum version of the common language runtime (CLR) required by this module + CLRVersion = '4.0' + + # Functions to export from this module + FunctionsToExport = '*' + + # Cmdlets to export from this module + CmdletsToExport = '*' + + RequiredAssemblies = @() + + # Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. + PrivateData = @{ + + PSData = @{ + + # Tags applied to this module. These help with module discovery in online galleries. + Tags = @('DesiredStateConfiguration', 'DSC', 'DSCResourceKit', 'DSCResource') + + # A URL to the license for this module. + LicenseUri = 'https://github.com/PowerShell/SqlServerDsc/blob/master/LICENSE' + + # A URL to the main website for this project. + ProjectUri = 'https://github.com/PowerShell/SqlServerDsc' + + # A URL to an icon representing this module. + # IconUri = '' + + # ReleaseNotes of this module + ReleaseNotes = '- Changes to SqlServerDsc + - BREAKING CHANGE: Resource SqlRSSecureConnectionLevel was remove + ([issue 990](https://github.com/PowerShell/SqlServerDsc/issues/990)). + The parameter that was set using that resource has been merged into resource + SqlRS as the parameter UseSsl. The UseSsl parameter is of type boolean. This + change was made because from SQL Server 2008 R2 this value is made an on/off + switch. Read more in the article [ConfigurationSetting Method - SetSecureConnectionLevel](https://docs.microsoft.com/en-us/sql/reporting-services/wmi-provider-library-reference/configurationsetting-method-setsecureconnectionlevel). + - Updated so that named parameters are used for New-Object cmdlet. This was + done to follow the style guideline. + - Updated manifest and license to reflect the new year + ([issue 965](https://github.com/PowerShell/SqlServerDsc/issues/965)). + - Added a README.md under Tests\Integration to help contributors to write + integration tests. + - Added "Integration tests" section in the CONTRIBUTING.md. + - The complete examples were removed. They were no longer accurate and some + referenced resources that no longer exist. Accurate examples can be found + in each specific resource example folder. Examples for installing Failover Cluster + can be found in the resource examples folders in the xFailOverCluster + resource module ([issue 462](https://github.com/PowerShell/SqlServerDsc/issues/462)). + - A README.md was created under the Examples folder to be used as reference how + to install certain scenarios ([issue 462](https://github.com/PowerShell/SqlServerDsc/issues/462)). + - Removed the local specific common test for compiling examples in this repository + and instead opted-in for the common test in the "DscResource.Tests" repository + ([issue 669](https://github.com/PowerShell/SqlServerDsc/issues/669)). + - Added new resource SqlServerDatabaseMail for configuring SQL Server + Database Mail ([issue 155](https://github.com/PowerShell/SqlServerDsc/issues/155)). + - Updated the helper function Test-SQLDscParameterState to handle the + data type UInt16. + - Fixed typo in SqlServerDscCommon.Tests. + - Updated README.md with known issue section for each resource. + - Resources that did not have a description in the README.md now has one. + - Resources that missed links to the examples in the README.md now has those + links. + - Style changes in all examples, removing type [System.Management.Automation.Credential()] + from credential parameters ([issue 1003](https://github.com/PowerShell/SqlServerDsc/issues/1003)), + and renamed the credential parameter so it is not using abbreviation. + - Updated the security token for AppVeyor status badge in README.md. When we + renamed the repository the security token was changed + ([issue 1012](https://github.com/PowerShell/SqlServerDsc/issues/1012)). + - Now the helper function Restart-SqlService, after restarting the SQL Server + service, does not return until it can connect to the SQL Server instance, and + the instance returns status "Online" ([issue 1008](https://github.com/PowerShell/SqlServerDsc/issues/1008)). + If it fails to connect within the timeout period (defaults to 120 seconds) it + throws an error. + - Fixed typo in comment-base help for helper function Test-AvailabilityReplicaSeedingModeAutomatic. + - Style cleanup in helper functions and tests. +- Changes to SqlAG + - Fixed typos in tests. + - Style cleanup in code and tests. +- Changes to SqlAGDatabase + - Style cleanup in code and tests. +- Changes to SqlAGListener + - Fixed typo in comment-based help. + - Style cleanup in code and tests. +- Changes to SqlAGReplica + - Minor code style cleanup. Removed unused variable and instead piped the cmdlet + Join-SqlAvailabilityGroup to Out-Null. + - Fixed minor typos in comment-based help. + - Fixed minor typos in comment. + - Style cleanup in code and tests. + - Updated description for parameter Name in README.md and in comment-based help + ([issue 1034](https://github.com/PowerShell/SqlServerDsc/issues/1034)). +- Changes to SqlAlias + - Fixed issue where exception was thrown if reg keys did not exist + ([issue 949](https://github.com/PowerShell/SqlServerDsc/issues/949)). + - Style cleanup in tests. +- Changes to SqlAlwaysOnService + - Refactor integration tests slightly to improve run time performance + ([issue 1001](https://github.com/PowerShell/SqlServerDsc/issues/1001)). + - Style cleanup in code and tests. +- Changes to SqlDatabase + - Fix minor Script Analyzer warning. +- Changes to SqlDatabaseDefaultLocation + - Refactor integration tests slightly to improve run time performance + ([issue 1001](https://github.com/PowerShell/SqlServerDsc/issues/1001)). + - Minor style cleanup of code in tests. +- Changes to SqlDatabaseRole + - Style cleanup in tests. +- Changes to SqlRS + - Replaced Get-WmiObject with Get-CimInstance to fix Script Analyzer warnings + ([issue 264](https://github.com/PowerShell/SqlServerDsc/issues/264)). + - Refactored the resource to use Invoke-CimMethod. + - Added parameter UseSsl which when set to $true forces connections to the + Reporting Services to use SSL when connecting ([issue 990](https://github.com/PowerShell/SqlServerDsc/issues/990)). + - Added complete example for SqlRS (based on the integration tests) + ([issue 634](https://github.com/PowerShell/SqlServerDsc/issues/634)). + - Refactor integration tests slightly to improve run time performance + ([issue 1001](https://github.com/PowerShell/SqlServerDsc/issues/1001)). + - Style cleanup in code and tests. +- Changes to SqlScript + - Style cleanup in tests. + - Updated examples. + - Added integration tests. + - Fixed minor typos in comment-based help. + - Added new example based on integration test. +- Changes to SqlServerConfiguration + - Fixed minor typos in comment-based help. + - Now the verbose message say what option is changing and to what value + ([issue 1014](https://github.com/PowerShell/SqlServerDsc/issues/1014)). + - Changed the RestartTimeout parameter from type SInt32 to type UInt32. + - Added localization ([issue 605](https://github.com/PowerShell/SqlServerDsc/issues/605)). + - Style cleanup in code and tests. +- Changes to SqlServerEndpoint + - Updated README.md with links to the examples + ([issue 504](https://github.com/PowerShell/SqlServerDsc/issues/504)). + - Style cleanup in tests. +- Changes to SqlServerLogin + - Added integration tests ([issue 748](https://github.com/PowerShell/SqlServerDsc/issues/748)). + - Minor code style cleanup. + - Removed unused variable and instead piped the helper function Connect-SQL to + Out-Null. + - Style cleanup in tests. +- Changes to SqlServerMaxDop + - Minor style changes in the helper function Get-SqlDscDynamicMaxDop. +- Changes to SqlServerMemory + - Style cleanup in code and tests. +- Changes to SqlServerPermission + - Fixed minor typos in comment-based help. + - Style cleanup in code. +- Changes to SqlServerReplication + - Fixed minor typos in verbose messages. + - Style cleanup in tests. +- Changes to SqlServerNetwork + - Added sysadmin account parameter usage to the examples. +- Changes to SqlServerReplication + - Fix Script Analyzer warning ([issue 263](https://github.com/PowerShell/SqlServerDsc/issues/263)). +- Changes to SqlServerRole + - Added localization ([issue 621](https://github.com/PowerShell/SqlServerDsc/issues/621)). + - Added integration tests ([issue 756](https://github.com/PowerShell/SqlServerDsc/issues/756)). + - Updated example to add two server roles in the same configuration. + - Style cleanup in tests. +- Changes to SqlServiceAccount + - Default services are now properly detected + ([issue 930](https://github.com/PowerShell/SqlServerDsc/issues/930)). + - Made the description of parameter RestartService more descriptive + ([issue 960](https://github.com/PowerShell/SqlServerDsc/issues/960)). + - Added a read-only parameter ServiceAccountName so that the service account + name is correctly returned as a string ([issue 982](https://github.com/PowerShell/SqlServerDsc/issues/982)). + - Added integration tests ([issue 980](https://github.com/PowerShell/SqlServerDsc/issues/980)). + - The timing issue that the resource returned before SQL Server service was + actually restarted has been solved by a change in the helper function + Restart-SqlService ([issue 1008](https://github.com/PowerShell/SqlServerDsc/issues/1008)). + Now Restart-SqlService waits for the instance to return status "Online" or + throws an error saying it failed to connect within the timeout period. + - Style cleanup in code and tests. +- Changes to SqlSetup + - Added parameter `ASServerMode` to support installing Analysis Services in + Multidimensional mode, Tabular mode and PowerPivot mode + ([issue 388](https://github.com/PowerShell/SqlServerDsc/issues/388)). + - Added integration tests for testing Analysis Services Multidimensional mode + and Tabular mode. + - Cleaned up integration tests. + - Added integration tests for installing a default instance of Database Engine. + - Refactor integration tests slightly to improve run time performance + ([issue 1001](https://github.com/PowerShell/SqlServerDsc/issues/1001)). + - Added PSSA rule "PSUseDeclaredVarsMoreThanAssignments" override in the + function Set-TargetResource for the variable $global:DSCMachineStatus. + - Style cleanup in code and tests. +- Changes to SqlWaitForAG + - Style cleanup in code. +- Changes to SqlWindowsFirewall + - Fixed minor typos in comment-based help. + - Style cleanup in code. + +' + + } # End of PSData hashtable + + } # End of PrivateData hashtable + } + + + + + + + + + + + + diff --git a/lib/puppet_x/dsc_resources/SqlServerDsc/SqlServerDscHelper.psm1 b/lib/puppet_x/dsc_resources/SqlServerDsc/SqlServerDscHelper.psm1 new file mode 100644 index 000000000..e961ff804 --- /dev/null +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/SqlServerDscHelper.psm1 @@ -0,0 +1,1400 @@ +# Load Localization Data +Import-Module -Name (Join-Path -Path (Join-Path -Path $PSScriptRoot ` + -ChildPath 'DscResources') ` + -ChildPath 'CommonResourceHelper.psm1') + +$script:localizedData = Get-LocalizedData -ResourceName 'SqlServerDscHelper' -ScriptRoot $PSScriptRoot + +<# + .SYNOPSIS + Connect to a SQL Server Database Engine and return the server object. + + .PARAMETER SQLServer + String containing the host name of the SQL Server to connect to. + + .PARAMETER SQLInstanceName + String containing the SQL Server Database Engine instance to connect to. + + .PARAMETER SetupCredential + PSCredential object with the credentials to use to impersonate a user when connecting. + If this is not provided then the current user will be used to connect to the SQL Server Database Engine instance. +#> +function Connect-SQL +{ + [CmdletBinding()] + param + ( + [ValidateNotNull()] + [System.String] + $SQLServer = $env:COMPUTERNAME, + + [ValidateNotNull()] + [System.String] + $SQLInstanceName = 'MSSQLSERVER', + + [ValidateNotNull()] + [System.Management.Automation.PSCredential] + $SetupCredential + ) + + Import-SQLPSModule + + if ($SQLInstanceName -eq 'MSSQLSERVER') + { + $databaseEngineInstance = $SQLServer + } + else + { + $databaseEngineInstance = "$SQLServer\$SQLInstanceName" + } + + if ($SetupCredential) + { + $sql = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Server + $sql.ConnectionContext.ConnectAsUser = $true + $sql.ConnectionContext.ConnectAsUserPassword = $SetupCredential.GetNetworkCredential().Password + $sql.ConnectionContext.ConnectAsUserName = $SetupCredential.GetNetworkCredential().UserName + $sql.ConnectionContext.ServerInstance = $databaseEngineInstance + $sql.ConnectionContext.Connect() + } + else + { + $sql = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Server -ArgumentList $databaseEngineInstance + } + + if ( $sql.Status -match '^Online$' ) + { + Write-Verbose -Message ($script:localizedData.ConnectedToDatabaseEngineInstance -f $databaseEngineInstance) -Verbose + return $sql + } + else + { + $errorMessage = $script:localizedData.FailedToConnectToDatabaseEngineInstance -f $databaseEngineInstance + New-InvalidOperationException -Message $errorMessage + } +} + +<# + .SYNOPSIS + Connect to a SQL Server Analysis Service and return the server object. + + .PARAMETER SQLServer + String containing the host name of the SQL Server to connect to. + + .PARAMETER SQLInstanceName + String containing the SQL Server Analysis Service instance to connect to. + + .PARAMETER SetupCredential + PSCredential object with the credentials to use to impersonate a user when connecting. + If this is not provided then the current user will be used to connect to the SQL Server Analysis Service instance. +#> +function Connect-SQLAnalysis +{ + [CmdletBinding()] + param + ( + [Parameter()] + [ValidateNotNullOrEmpty()] + [System.String] + $SQLServer = $env:COMPUTERNAME, + + [Parameter()] + [ValidateNotNullOrEmpty()] + [System.String] + $SQLInstanceName = 'MSSQLSERVER', + + [Parameter()] + [ValidateNotNullOrEmpty()] + [System.Management.Automation.PSCredential] + [System.Management.Automation.Credential()] + $SetupCredential + ) + + $null = [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.AnalysisServices') + + if ($SQLInstanceName -eq 'MSSQLSERVER') + { + $analysisServiceInstance = $SQLServer + } + else + { + $analysisServiceInstance = "$SQLServer\$SQLInstanceName" + } + + if ($SetupCredential) + { + $userName = $SetupCredential.GetNetworkCredential().UserName + $password = $SetupCredential.GetNetworkCredential().Password + + $analysisServicesDataSource = "Data Source=$analysisServiceInstance;User ID=$userName;Password=$password" + } + else + { + $analysisServicesDataSource = "Data Source=$analysisServiceInstance" + } + + try + { + $analysisServicesObject = New-Object -TypeName Microsoft.AnalysisServices.Server + if ($analysisServicesObject) + { + $analysisServicesObject.Connect($analysisServicesDataSource) + } + else + { + $errorMessage = $script:localizedData.FailedToConnectToAnalysisServicesInstance -f $analysisServiceInstance + New-InvalidOperationException -Message $errorMessage + } + + Write-Verbose -Message ($script:localizedData.ConnectedToAnalysisServicesInstance -f $analysisServiceInstance) -Verbose + } + catch + { + $errorMessage = $script:localizedData.FailedToConnectToAnalysisServicesInstance -f $analysisServiceInstance + New-InvalidOperationException -Message $errorMessage -ErrorRecord $_ + } + + return $analysisServicesObject +} + +<# + .SYNOPSIS + Creates a new application domain and loads the assemblies Microsoft.SqlServer.Smo + for the correct SQL Server major version. + + An isolated application domain is used to load version specific assemblies, this needed + if there is multiple versions of SQL server in the same configuration. So that a newer + version of SQL is not using an older version of the assembly, or vice verse. + + This should be unloaded using the helper function Unregister-SqlAssemblies or + using [System.AppDomain]::Unload($applicationDomainObject). + + .PARAMETER SQLInstanceName + String containing the SQL Server Database Engine instance name to get the major SQL version from. + + .PARAMETER ApplicationDomain + An optional System.AppDomain object to load the assembly into. + + .OUTPUTS + System.AppDomain. Returns the application domain object with SQL SMO loaded. +#> +function Register-SqlSmo +{ + [CmdletBinding()] + [OutputType([System.AppDomain])] + param + ( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $SQLInstanceName, + + [Parameter()] + [ValidateNotNullOrEmpty()] + [System.AppDomain] + $ApplicationDomain + ) + + $sqlMajorVersion = Get-SqlInstanceMajorVersion -SQLInstanceName $SQLInstanceName + + Write-Verbose -Message ($script:localizedData.SqlMajorVersion -f $sqlMajorVersion) -Verbose + + if ( -not $ApplicationDomain ) + { + $applicationDomainName = $MyInvocation.MyCommand.ModuleName + Write-Verbose -Message ($script:localizedData.CreatingApplicationDomain -f $applicationDomainName) -Verbose + $applicationDomainObject = [System.AppDomain]::CreateDomain($applicationDomainName) + } + else + { + Write-Verbose -Message ($script:localizedData.ReusingApplicationDomain -f $ApplicationDomain.FriendlyName) -Verbose + $applicationDomainObject = $ApplicationDomain + } + + $sqlSmoAssemblyName = "Microsoft.SqlServer.Smo, Version=$sqlMajorVersion.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" + Write-Verbose -Message ($script:localizedData.LoadingAssembly -f $sqlSmoAssemblyName) -Verbose + $applicationDomainObject.Load($sqlSmoAssemblyName) | Out-Null + + return $applicationDomainObject +} + +<# + .SYNOPSIS + Creates a new application domain and loads the assemblies Microsoft.SqlServer.Smo and + Microsoft.SqlServer.SqlWmiManagement for the correct SQL Server major version. + + An isolated application domain is used to load version specific assemblies, this needed + if there is multiple versions of SQL server in the same configuration. So that a newer + version of SQL is not using an older version of the assembly, or vice verse. + + This should be unloaded using the helper function Unregister-SqlAssemblies or + using [System.AppDomain]::Unload($applicationDomainObject) preferably in a finally block. + + .PARAMETER SQLInstanceName + String containing the SQL Server Database Engine instance name to get the major SQL version from. + + .PARAMETER ApplicationDomain + An optional System.AppDomain object to load the assembly into. + + .OUTPUTS + System.AppDomain. Returns the application domain object with SQL WMI Management loaded. +#> +function Register-SqlWmiManagement +{ + [CmdletBinding()] + [OutputType([System.AppDomain])] + param + ( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $SQLInstanceName, + + [Parameter()] + [ValidateNotNull()] + [System.AppDomain] + $ApplicationDomain + ) + + $sqlMajorVersion = Get-SqlInstanceMajorVersion -SQLInstanceName $SQLInstanceName + Write-Verbose -Message ($script:localizedData.SqlMajorVersion -f $sqlMajorVersion) -Verbose + + <# + Must register Microsoft.SqlServer.Smo first because that is a + dependency of Microsoft.SqlServer.SqlWmiManagement. + #> + if (-not $ApplicationDomain) + { + $applicationDomainObject = Register-SqlSmo -SQLInstanceName $SQLInstanceName + } + # Returns zero (0) objects if the assembly is not found + elseif (-not ($ApplicationDomain.GetAssemblies().FullName -match 'Microsoft.SqlServer.Smo')) + { + $applicationDomainObject = Register-SqlSmo -SQLInstanceName $SQLInstanceName -ApplicationDomain $ApplicationDomain + } + + $sqlSqlWmiManagementAssemblyName = "Microsoft.SqlServer.SqlWmiManagement, Version=$sqlMajorVersion.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91" + Write-Verbose -Message ($script:localizedData.LoadingAssembly -f $sqlSqlWmiManagementAssemblyName) -Verbose + $applicationDomainObject.Load($sqlSqlWmiManagementAssemblyName) | Out-Null + + return $applicationDomainObject +} + +<# + .SYNOPSIS + Unloads all assemblies in an application domain. It unloads the application domain. + + .PARAMETER ApplicationDomain + System.AppDomain object containing the SQL assemblies to unload. +#> +function Unregister-SqlAssemblies +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [ValidateNotNull()] + [System.AppDomain] + $ApplicationDomain + ) + + Write-Verbose -Message ($script:localizedData.UnloadingApplicationDomain -f $ApplicationDomain.FriendlyName) -Verbose + [System.AppDomain]::Unload($ApplicationDomain) +} + +<# + .SYNOPSIS + Returns the major SQL version for the specific instance. + + .PARAMETER SQLInstanceName + String containing the name of the SQL instance to be configured. Default value is 'MSSQLSERVER'. + + .OUTPUTS + System.UInt16. Returns the SQL Server major version number. +#> +function Get-SqlInstanceMajorVersion +{ + [CmdletBinding()] + [OutputType([System.UInt16])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $SQLInstanceName = 'MSSQLSERVER' + ) + + $sqlInstanceId = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL').$SQLInstanceName + $sqlVersion = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$sqlInstanceId\Setup").Version + + if (-not $sqlVersion) + { + $errorMessage = $script:localizedData.SqlServerVersionIsInvalid -f $SQLInstanceName + New-InvalidResultException -Message $errorMessage + } + + [System.UInt16] $sqlMajorVersionNumber = $sqlVersion.Split('.')[0] + + return $sqlMajorVersionNumber +} + +<# + .SYNOPSIS + Returns a localized error message. + + This helper function is obsolete, should use new helper functions. + https://github.com/PowerShell/SqlServerDsc/blob/dev/CONTRIBUTING.md#localization + https://github.com/PowerShell/SqlServerDsc/blob/dev/DSCResources/CommonResourceHelper.psm1 + + Strings in this function has not been localized since this helper function should be removed + when all resources has moved over to the new localization, + + .PARAMETER ErrorType + String containing the key of the localized error message. + + .PARAMETER FormatArgs + Collection of strings to replace format objects in the error message. + + .PARAMETER ErrorCategory + The category to use for the error message. Default value is 'OperationStopped'. + Valid values are a value from the enumeration System.Management.Automation.ErrorCategory. + + .PARAMETER TargetObject + The object that was being operated on when the error occurred. + + .PARAMETER InnerException + Exception object that was thrown when the error occurred, which will be added to the final error message. +#> +function New-TerminatingError +{ + [CmdletBinding()] + [OutputType([System.Management.Automation.ErrorRecord])] + param + ( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $ErrorType, + + [Parameter(Mandatory = $false)] + [System.String[]] + $FormatArgs, + + [Parameter(Mandatory = $false)] + [System.Management.Automation.ErrorCategory] + $ErrorCategory = [System.Management.Automation.ErrorCategory]::OperationStopped, + + [Parameter(Mandatory = $false)] + [System.Object] + $TargetObject = $null, + + [Parameter(Mandatory = $false)] + [System.Exception] + $InnerException = $null + ) + + $errorMessage = $script:localizedData.$ErrorType + + if(!$errorMessage) + { + $errorMessage = ($script:localizedData.NoKeyFound -f $ErrorType) + + if(!$errorMessage) + { + $errorMessage = ("No Localization key found for key: {0}" -f $ErrorType) + } + } + + $errorMessage = ($errorMessage -f $FormatArgs) + + if( $InnerException ) + { + $errorMessage += " InnerException: $($InnerException.Message)" + } + + $callStack = Get-PSCallStack + + # Get Name of calling script + if($callStack[1] -and $callStack[1].ScriptName) + { + $scriptPath = $callStack[1].ScriptName + + $callingScriptName = $scriptPath.Split('\')[-1].Split('.')[0] + + $errorId = "$callingScriptName.$ErrorType" + } + else + { + $errorId = $ErrorType + } + + Write-Verbose -Message "$($script:localizedData.$ErrorType -f $FormatArgs) | ErrorType: $errorId" + + $exception = New-Object -TypeName System.Exception -ArgumentList $errorMessage, $InnerException + $errorRecord = New-Object -TypeName System.Management.Automation.ErrorRecord -ArgumentList $exception, $errorId, $ErrorCategory, $TargetObject + + return $errorRecord +} + +<# + .SYNOPSIS + Displays a localized warning message. + + This helper function is obsolete, should use Write-Warning together with individual resource + localization strings. + https://github.com/PowerShell/SqlServerDsc/blob/dev/CONTRIBUTING.md#localization + + Strings in this function has not been localized since this helper function should be removed + when all resources has moved over to the new localization, + + .PARAMETER WarningType + String containing the key of the localized warning message. + + .PARAMETER FormatArgs + Collection of strings to replace format objects in warning message. +#> +function New-WarningMessage +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $WarningType, + + [Parameter()] + [System.String[]] + $FormatArgs + ) + + ## Attempt to get the string from the localized data + $warningMessage = $script:localizedData.$WarningType + + ## Ensure there is a message present in the localization file + if (!$warningMessage) + { + $errorParams = @{ + ErrorType = 'NoKeyFound' + FormatArgs = $WarningType + ErrorCategory = 'InvalidArgument' + TargetObject = 'New-WarningMessage' + } + + ## Raise an error indicating the localization data is not present + throw New-TerminatingError @errorParams + } + + ## Apply formatting + $warningMessage = $warningMessage -f $FormatArgs + + ## Write the message as a warning + Write-Warning -Message $warningMessage +} + +<# + .SYNOPSIS + Displays a standardized verbose message. + + This helper function is obsolete, should use Write-Verbose together with individual resource + localization strings. + https://github.com/PowerShell/SqlServerDsc/blob/dev/CONTRIBUTING.md#localization + + Strings in this function has not been localized since this helper function should be removed + when all resources has moved over to the new localization, + + .PARAMETER Message + String containing the key of the localized warning message. +#> +function New-VerboseMessage +{ + [CmdletBinding()] + [Alias()] + [OutputType([System.String])] + Param + ( + [Parameter(Mandatory = $true)] + [System.String] + $Message + ) + Write-Verbose -Message ((Get-Date -format yyyy-MM-dd_HH-mm-ss) + ": $Message") -Verbose +} + +<# + .SYNOPSIS + This method is used to compare current and desired values for any DSC resource. + + .PARAMETER CurrentValues + This is hash table of the current values that are applied to the resource. + + .PARAMETER DesiredValues + This is a PSBoundParametersDictionary of the desired values for the resource. + + .PARAMETER ValuesToCheck + This is a list of which properties in the desired values list should be checked. + If this is empty then all values in DesiredValues are checked. +#> +function Test-SQLDscParameterState +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [System.Collections.Hashtable] + $CurrentValues, + + [Parameter(Mandatory = $true)] + [System.Object] + $DesiredValues, + + [Parameter()] + [System.Array] + $ValuesToCheck + ) + + $returnValue = $true + + if (($DesiredValues.GetType().Name -ne 'HashTable') ` + -and ($DesiredValues.GetType().Name -ne 'CimInstance') ` + -and ($DesiredValues.GetType().Name -ne 'PSBoundParametersDictionary')) + { + $errorMessage = $script:localizedData.PropertyTypeInvalidForDesiredValues -f $($DesiredValues.GetType().Name) + New-InvalidArgumentException -ArgumentName 'DesiredValues' -Message $errorMessage + } + + if (($DesiredValues.GetType().Name -eq 'CimInstance') -and ($null -eq $ValuesToCheck)) + { + $errorMessage = $script:localizedData.PropertyTypeInvalidForValuesToCheck + New-InvalidArgumentException -ArgumentName 'ValuesToCheck' -Message $errorMessage + } + + if (($null -eq $ValuesToCheck) -or ($ValuesToCheck.Count -lt 1)) + { + $keyList = $DesiredValues.Keys + } + else + { + $keyList = $ValuesToCheck + } + + $keyList | ForEach-Object -Process { + if (($_ -ne 'Verbose')) + { + if (($CurrentValues.ContainsKey($_) -eq $false) ` + -or ($CurrentValues.$_ -ne $DesiredValues.$_) ` + -or (($DesiredValues.GetType().Name -ne 'CimInstance' -and $DesiredValues.ContainsKey($_) -eq $true) -and ($null -ne $DesiredValues.$_ -and $DesiredValues.$_.GetType().IsArray))) + { + if ($DesiredValues.GetType().Name -eq 'HashTable' -or ` + $DesiredValues.GetType().Name -eq 'PSBoundParametersDictionary') + { + $checkDesiredValue = $DesiredValues.ContainsKey($_) + } + else + { + # If DesiredValue is a CimInstance. + $checkDesiredValue = $false + if (([System.Boolean]($DesiredValues.PSObject.Properties.Name -contains $_)) -eq $true) + { + if ($null -ne $DesiredValues.$_) + { + $checkDesiredValue = $true + } + } + } + + if ($checkDesiredValue) + { + $desiredType = $DesiredValues.$_.GetType() + $fieldName = $_ + if ($desiredType.IsArray -eq $true) + { + if (($CurrentValues.ContainsKey($fieldName) -eq $false) ` + -or ($null -eq $CurrentValues.$fieldName)) + { + Write-Verbose -Message ($script:localizedData.PropertyValidationError -f $fieldName) -Verbose + + $returnValue = $false + } + else + { + $arrayCompare = Compare-Object -ReferenceObject $CurrentValues.$fieldName ` + -DifferenceObject $DesiredValues.$fieldName + if ($null -ne $arrayCompare) + { + Write-Verbose -Message ($script:localizedData.PropertiesDoesNotMatch -f $fieldName) -Verbose + + $arrayCompare | ForEach-Object -Process { + Write-Verbose -Message ($script:localizedData.PropertyThatDoesNotMatch -f $_.InputObject, $_.SideIndicator) -Verbose + } + + $returnValue = $false + } + } + } + else + { + switch ($desiredType.Name) + { + 'String' + { + if (-not [System.String]::IsNullOrEmpty($CurrentValues.$fieldName) -or ` + -not [System.String]::IsNullOrEmpty($DesiredValues.$fieldName)) + { + Write-Verbose -Message ($script:localizedData.ValueOfTypeDoesNotMatch ` + -f $desiredType.Name, $fieldName, $($CurrentValues.$fieldName), $($DesiredValues.$fieldName)) -Verbose + + $returnValue = $false + } + } + + 'Int32' + { + if (-not ($DesiredValues.$fieldName -eq 0) -or ` + -not ($null -eq $CurrentValues.$fieldName)) + { + Write-Verbose -Message ($script:localizedData.ValueOfTypeDoesNotMatch ` + -f $desiredType.Name, $fieldName, $($CurrentValues.$fieldName), $($DesiredValues.$fieldName)) -Verbose + + $returnValue = $false + } + } + + { $_ -eq 'Int16' -or $_ -eq 'UInt16'} + { + if (-not ($DesiredValues.$fieldName -eq 0) -or ` + -not ($null -eq $CurrentValues.$fieldName)) + { + Write-Verbose -Message ($script:localizedData.ValueOfTypeDoesNotMatch ` + -f $desiredType.Name, $fieldName, $($CurrentValues.$fieldName), $($DesiredValues.$fieldName)) -Verbose + + $returnValue = $false + } + } + + default + { + Write-Warning -Message ($script:localizedData.UnableToCompareProperty ` + -f $fieldName, $desiredType.Name) + + $returnValue = $false + } + } + } + } + } + } + } + + return $returnValue +} + +<# + .SYNOPSIS + Imports the module SQLPS in a standardized way. +#> +function Import-SQLPSModule +{ + [CmdletBinding()] + param + ( + ) + + $module = (Get-Module -FullyQualifiedName 'SqlServer' -ListAvailable).Name + if ($module) + { + Write-Verbose -Message ($script:localizedData.PreferredModuleFound) -Verbose + } + else + { + Write-Verbose -Message ($script:localizedData.PreferredModuleNotFound) -Verbose + + <# + After installing SQL Server the current PowerShell session doesn't know about the new path + that was added for the SQLPS module. + This reloads PowerShell session environment variable PSModulePath to make sure it contains + all paths. + #> + $env:PSModulePath = [System.Environment]::GetEnvironmentVariable('PSModulePath', 'Machine') + + $module = (Get-Module -FullyQualifiedName 'SQLPS' -ListAvailable).Name + } + + if ($module) + { + try + { + Write-Debug -Message ($script:localizedData.DebugMessagePushingLocation) + Push-Location + + Write-Verbose -Message ($script:localizedData.ImportingPowerShellModule -f $module) -Verbose + + <# + SQLPS has unapproved verbs, disable checking to ignore Warnings. + Suppressing verbose so all cmdlet is not listed. + #> + Import-Module -Name $module -DisableNameChecking -Verbose:$False -ErrorAction Stop + + Write-Debug -Message ($script:localizedData.DebugMessageImportedPowerShellModule -f $module) + } + catch + { + $errorMessage = $script:localizedData.FailedToImportPowerShellSqlModule -f $module + New-InvalidOperationException -Message $errorMessage -ErrorRecord $_ + } + finally + { + Write-Debug -Message ($script:localizedData.DebugMessagePoppingLocation) + Pop-Location + } + } + else + { + $errorMessage = $script:localizedData.PowerShellSqlModuleNotFound + New-InvalidOperationException -Message $errorMessage + } +} + +<# + .SYNOPSIS + Restarts a SQL Server instance and associated services + + .PARAMETER SQLServer + Hostname of the SQL Server to be configured + + .PARAMETER SQLInstanceName + Name of the SQL instance to be configured. Default is 'MSSQLSERVER' + + .PARAMETER Timeout + Timeout value for restarting the SQL services. The default value is 120 seconds. + + .EXAMPLE + Restart-SqlService -SQLServer localhost + + .EXAMPLE + Restart-SqlService -SQLServer localhost -SQLInstanceName 'NamedInstance' + + .EXAMPLE + Restart-SqlService -SQLServer CLU01 -Timeout 300 +#> +function Restart-SqlService +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $SQLServer, + + [Parameter()] + [System.String] + $SQLInstanceName = 'MSSQLSERVER', + + [Parameter()] + [System.UInt32] + $Timeout = 120 + ) + + ## Connect to the instance + $serverObject = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName + + if ($serverObject.IsClustered) + { + # Get the cluster resources + Write-Verbose -Message ($script:localizedData.GetSqlServerClusterResources) -Verbose + $sqlService = Get-CimInstance -Namespace root/MSCluster -ClassName MSCluster_Resource -Filter "Type = 'SQL Server'" | + Where-Object -FilterScript { $_.PrivateProperties.InstanceName -eq $serverObject.ServiceName } + + Write-Verbose -Message ($script:localizedData.GetSqlAgentClusterResource) -Verbose + $agentService = $sqlService | Get-CimAssociatedInstance -ResultClassName MSCluster_Resource | + Where-Object -FilterScript { ($_.Type -eq 'SQL Server Agent') -and ($_.State -eq 2) } + + # Build a listing of resources being acted upon + $resourceNames = @($sqlService.Name, ($agentService | Select-Object -ExpandProperty Name)) -join "," + + # Stop the SQL Server and dependent resources + Write-Verbose -Message ($script:localizedData.BringClusterResourcesOffline -f $resourceNames) -Verbose + $sqlService | Invoke-CimMethod -MethodName TakeOffline -Arguments @{ Timeout = $Timeout } + + # Start the SQL server resource + Write-Verbose -Message ($script:localizedData.BringSqlServerClusterResourcesOnline) -Verbose + $sqlService | Invoke-CimMethod -MethodName BringOnline -Arguments @{ Timeout = $Timeout } + + # Start the SQL Agent resource + if ($agentService) + { + Write-Verbose -Message ($script:localizedData.BringSqlServerAgentClusterResourcesOnline) -Verbose + $agentService | Invoke-CimMethod -MethodName BringOnline -Arguments @{ Timeout = $Timeout } + } + } + else + { + Write-Verbose -Message ($script:localizedData.GetServiceInformation -f 'SQL Server') -Verbose + $sqlService = Get-Service -DisplayName "SQL Server ($($serverObject.ServiceName))" + + <# + Get all dependent services that are running. + There are scenarios where an automatic service is stopped and should not be restarted automatically. + #> + $agentService = $sqlService.DependentServices | Where-Object -FilterScript { $_.Status -eq 'Running' } + + # Restart the SQL Server service + Write-Verbose -Message ($script:localizedData.RestartService -f 'SQL Server') -Verbose + $sqlService | Restart-Service -Force + + # Start dependent services + $agentService | ForEach-Object { + Write-Verbose -Message ($script:localizedData.StartingDependentService -f $_.DisplayName) -Verbose + $_ | Start-Service + } + } + + Write-Verbose -Message ($script:localizedData.WaitingInstanceTimeout -f $SQLServer, $SQLInstanceName, $Timeout) -Verbose + + $connectTimer = [System.Diagnostics.StopWatch]::StartNew() + + do + { + # This call, if it fails, will take between ~9-10 seconds to return. + $testConnectionServerObject = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName -ErrorAction SilentlyContinue + if ($testConnectionServerObject -and $testConnectionServerObject.Status -ne 'Online') + { + # Waiting 2 seconds to not hammer the SQL Server instance. + Start-Sleep -Seconds 2 + } + else + { + break + } + } until ($connectTimer.Elapsed.Seconds -ge $Timeout) + + $connectTimer.Stop() + + # Was the timeout period reach before able to connect to the SQL Server instance? + if (-not $testConnectionServerObject -or $testConnectionServerObject.Status -ne 'Online') + { + $errorMessage = $script:localizedData.FailedToConnectToInstanceTimeout -f $SQLServer, $SQLInstanceName, $Timeout + New-InvalidOperationException -Message $errorMessage + } +} + +<# + .SYNOPSIS + Restarts a Reporting Services instance and associated services + + .PARAMETER SQLInstanceName + Name of the instance to be restarted. Default is 'MSSQLSERVER' + (the default instance). +#> +function Restart-ReportingServicesService +{ + [CmdletBinding()] + param + ( + [Parameter()] + [System.String] + $SQLInstanceName = 'MSSQLSERVER' + ) + + $ServiceName = 'ReportServer' + + if (-not ($SQLInstanceName -eq 'MSSQLSERVER')) + { + $ServiceName += '${0}' -f $SQLInstanceName + } + + Write-Verbose -Message ($script:localizedData.GetServiceInformation -f 'Reporting Services') -Verbose + $reportingServicesService = Get-Service -Name $ServiceName + + <# + Get all dependent services that are running. + There are scenarios where an automatic service is stopped and should + not be restarted automatically. + #> + $dependentService = $reportingServicesService.DependentServices | Where-Object -FilterScript { + $_.Status -eq 'Running' + } + + Write-Verbose -Message ($script:localizedData.RestartService -f 'Reporting Services') -Verbose + $reportingServicesService | Restart-Service -Force + + # Start dependent services + $dependentService | ForEach-Object { + Write-Verbose -Message ($script:localizedData.StartingDependentService -f $_.DisplayName) -Verbose + $_ | Start-Service + } +} + +<# + .SYNOPSIS + Executes a query on the specified database. + + .PARAMETER SQLServer + The hostname of the server that hosts the SQL instance. + + .PARAMETER SQLInstanceName + The name of the SQL instance that hosts the database. + + .PARAMETER Database + Specify the name of the database to execute the query on. + + .PARAMETER Query + The query string to execute. + + .PARAMETER WithResults + Specifies if the query should return results. + + .EXAMPLE + Invoke-Query -SQLServer Server1 -SQLInstanceName MSSQLSERVER -Database master -Query 'SELECT name FROM sys.databases' -WithResults + + .EXAMPLE + Invoke-Query -SQLServer Server1 -SQLInstanceName MSSQLSERVER -Database master -Query 'RESTORE DATABASE [NorthWinds] WITH RECOVERY' +#> +function Invoke-Query +{ + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $SQLServer, + + [Parameter(Mandatory = $true)] + [System.String] + $SQLInstanceName, + + [Parameter(Mandatory = $true)] + [System.String] + $Database, + + [Parameter(Mandatory = $true)] + [System.String] + $Query, + + [Parameter()] + [Switch] + $WithResults + ) + + $serverObject = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName + + if ( $WithResults ) + { + try + { + $result = $serverObject.Databases[$Database].ExecuteWithResults($Query) + } + catch + { + $errorMessage = $script:localizedData.ExecuteQueryWithResultsFailed -f $Database + New-InvalidOperationException -Message $errorMessage -ErrorRecord $_ + } + } + else + { + try + { + $serverObject.Databases[$Database].ExecuteNonQuery($Query) + } + catch + { + $errorMessage = $script:localizedData.ExecuteNonQueryFailed -f $Database + New-InvalidOperationException -Message $errorMessage -ErrorRecord $_ + } + } + + return $result +} + +<# + .SYNOPSIS + Executes the alter method on an Availability Group Replica object. + + .PARAMETER AvailabilityGroupReplica + The Availability Group Replica object that must be altered. +#> +function Update-AvailabilityGroupReplica +{ + param + ( + [Parameter(Mandatory = $true)] + [Microsoft.SqlServer.Management.Smo.AvailabilityReplica] + $AvailabilityGroupReplica + ) + + try + { + $originalErrorActionPreference = $ErrorActionPreference + $ErrorActionPreference = 'Stop' + $AvailabilityGroupReplica.Alter() + } + catch + { + $errorMessage = $script:localizedData.AlterAvailabilityGroupReplicaFailed -f $AvailabilityGroupReplica.Name + New-InvalidOperationException -Message $errorMessage -ErrorRecord $_ + } + finally + { + $ErrorActionPreference = $originalErrorActionPreference + } +} + +function Test-LoginEffectivePermissions +{ + param + ( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $SQLServer, + + [Parameter(Mandatory = $true)] + [System.String] + $SQLInstanceName, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $LoginName, + + [Parameter(Mandatory = $true)] + [System.String[]] + $Permissions + ) + + # Assume the permissions are not present + $permissionsPresent = $false + + $invokeQueryParameters = @{ + SQLServer = $SQLServer + SQLInstanceName = $SQLInstanceName + Database = 'master' + WithResults = $true + } + + $queryToGetEffectivePermissionsForLogin = " + EXECUTE AS LOGIN = '$LoginName' + SELECT DISTINCT permission_name + FROM fn_my_permissions(null,'SERVER') + REVERT + " + + Write-Verbose -Message ($script:localizedData.GetEffectivePermissionForLogin -f $LoginName, $sqlInstanceName) -Verbose + + $loginEffectivePermissionsResult = Invoke-Query @invokeQueryParameters -Query $queryToGetEffectivePermissionsForLogin + $loginEffectivePermissions = $loginEffectivePermissionsResult.Tables.Rows.permission_name + + if ( $null -ne $loginEffectivePermissions ) + { + $loginMissingPermissions = Compare-Object -ReferenceObject $Permissions -DifferenceObject $loginEffectivePermissions | + Where-Object -FilterScript { $_.SideIndicator -ne '=>' } | + Select-Object -ExpandProperty InputObject + + if ( $loginMissingPermissions.Count -eq 0 ) + { + $permissionsPresent = $true + } + } + + return $permissionsPresent +} + +<# + .SYNOPSIS + Determine if the seeding mode of the specified availability group is automatic. + + .PARAMETER SQLServer + The hostname of the server that hosts the SQL instance. + + .PARAMETER SQLInstanceName + The name of the SQL instance that hosts the availability group. + + .PARAMETER AvailabilityGroupName + The name of the availability group to check. + + .PARAMETER AvailabilityReplicaName + The name of the availability replica to check. +#> +function Test-AvailabilityReplicaSeedingModeAutomatic +{ + param + ( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $SQLServer, + + [Parameter(Mandatory = $true)] + [System.String] + $SQLInstanceName, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $AvailabilityGroupName, + + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $AvailabilityReplicaName + ) + + # Assume automatic seeding is disabled by default + $availabilityReplicaSeedingModeAutomatic = $false + + $serverObject = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName + + # Only check the seeding mode if this is SQL 2016 or newer + if ( $serverObject.Version -ge 13 ) + { + $invokeQueryParams = @{ + SQLServer = $SQLServer + SQLInstanceName = $SQLInstanceName + Database = 'master' + WithResults = $true + } + + $queryToGetSeedingMode = " + SELECT seeding_mode_desc + FROM sys.availability_replicas ar + INNER JOIN sys.availability_groups ag ON ar.group_id = ag.group_id + WHERE ag.name = '$AvailabilityGroupName' + AND ar.replica_server_name = '$AvailabilityReplicaName' + " + $seedingModeResults = Invoke-Query @invokeQueryParams -Query $queryToGetSeedingMode + $seedingMode = $seedingModeResults.Tables.Rows.seeding_mode_desc + + if ( $seedingMode -eq 'Automatic' ) + { + $availabilityReplicaSeedingModeAutomatic = $true + } + } + + return $availabilityReplicaSeedingModeAutomatic +} + +<# + .SYNOPSIS + Get the server object of the primary replica of the specified availability group. + + .PARAMETER ServerObject + The current server object connection. + + .PARAMETER AvailabilityGroup + The availability group object used to find the primary replica server name. +#> +function Get-PrimaryReplicaServerObject +{ + param + ( + [Parameter(Mandatory = $true)] + [Microsoft.SqlServer.Management.Smo.Server] + $ServerObject, + + [Parameter(Mandatory = $true)] + [Microsoft.SqlServer.Management.Smo.AvailabilityGroup] + $AvailabilityGroup + ) + + $primaryReplicaServerObject = $serverObject + + # Determine if we're connected to the primary replica + if ( ( $AvailabilityGroup.PrimaryReplicaServerName -ne $serverObject.DomainInstanceName ) -and ( -not [System.String]::IsNullOrEmpty($AvailabilityGroup.PrimaryReplicaServerName) ) ) + { + $primaryReplicaServerObject = Connect-SQL -SQLServer $AvailabilityGroup.PrimaryReplicaServerName + } + + return $primaryReplicaServerObject +} + +<# + .SYNOPSIS + Determine if the current login has impersonate permissions + + .PARAMETER ServerObject + The server object on which to perform the test. +#> +function Test-ImpersonatePermissions +{ + param + ( + [Parameter(Mandatory = $true)] + [Microsoft.SqlServer.Management.Smo.Server] + $ServerObject + ) + + $testLoginEffectivePermissionsParams = @{ + SQLServer = $ServerObject.ComputerNamePhysicalNetBIOS + SQLInstanceName = $ServerObject.ServiceName + LoginName = $ServerObject.ConnectionContext.TrueLogin + Permissions = @('IMPERSONATE ANY LOGIN') + } + + $impersonatePermissionsPresent = Test-LoginEffectivePermissions @testLoginEffectivePermissionsParams + + if ( -not $impersonatePermissionsPresent ) + { + New-VerboseMessage -Message ( 'The login "{0}" does not have impersonate permissions on the instance "{1}\{2}".' -f $testLoginEffectivePermissionsParams.LoginName, $testLoginEffectivePermissionsParams.SQLServer, $testLoginEffectivePermissionsParams.SQLInstanceName ) + } + + return $impersonatePermissionsPresent +} + +<# + .SYNOPSIS + Takes a SQL Instance name in the format of 'Server\Instance' and splits it into a hash table prepared to be passed into Connect-SQL. + + .PARAMETER FullSQLInstanceName + The full SQL instance name string to be split. + + .OUTPUTS + Hash table with the properties SQLServer and SQLInstanceName. +#> +function Split-FullSQLInstanceName +{ + param + ( + [Parameter(Mandatory = $true)] + [ValidateNotNullOrEmpty()] + [System.String] + $FullSQLInstanceName + ) + + $sqlServer,$sqlInstanceName = $FullSQLInstanceName.Split('\') + + if ( [System.String]::IsNullOrEmpty($sqlInstanceName) ) + { + $sqlInstanceName = 'MSSQLSERVER' + } + + return @{ + SQLServer = $sqlServer + SQLInstanceName = $sqlInstanceName + } +} + +<# + .SYNOPSIS + Determine if the cluster has the required permissions to the supplied server. + + .PARAMETER ServerObject + The server object on which to perform the test. +#> +function Test-ClusterPermissions +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [Microsoft.SqlServer.Management.Smo.Server] + $ServerObject + ) + + $clusterServiceName = 'NT SERVICE\ClusSvc' + $ntAuthoritySystemName = 'NT AUTHORITY\SYSTEM' + $availabilityGroupManagementPerms = @('Connect SQL', 'Alter Any Availability Group', 'View Server State') + $clusterPermissionsPresent = $false + + # Retrieve the SQL Server and Instance name from the server object + $sqlServer = $ServerObject.NetName + $sqlInstanceName = $ServerObject.ServiceName + + foreach ( $loginName in @( $clusterServiceName, $ntAuthoritySystemName ) ) + { + if ( $ServerObject.Logins[$loginName] -and -not $clusterPermissionsPresent ) + { + $testLoginEffectivePermissionsParams = @{ + SQLServer = $sqlServer + SQLInstanceName = $sqlInstanceName + LoginName = $loginName + Permissions = $availabilityGroupManagementPerms + } + + $clusterPermissionsPresent = Test-LoginEffectivePermissions @testLoginEffectivePermissionsParams + + if ( -not $clusterPermissionsPresent ) + { + switch ( $loginName ) + { + $clusterServiceName + { + Write-Verbose -Message ( $script:localizedData.ClusterLoginMissingRecommendedPermissions -f $loginName,( $availabilityGroupManagementPerms -join ', ' ) ) -Verbose + } + + $ntAuthoritySystemName + { + Write-Verbose -Message ( $script:localizedData.ClusterLoginMissingPermissions -f $loginName,( $availabilityGroupManagementPerms -join ', ' ) ) -Verbose + } + } + } + else + { + Write-Verbose -Message ( $script:localizedData.ClusterLoginPermissionsPresent -f $loginName ) -Verbose + } + } + elseif ( -not $clusterPermissionsPresent ) + { + switch ( $loginName ) + { + $clusterServiceName + { + Write-Verbose -Message ($script:localizedData.ClusterLoginMissingRecommendedPermissions -f $loginName,"Trying with '$ntAuthoritySystemName'.") -Verbose + } + + $ntAuthoritySystemName + { + Write-Verbose -Message ( $script:localizedData.ClusterLoginMissing -f $loginName,'' ) -Verbose + } + } + } + } + + # If neither 'NT SERVICE\ClusSvc' or 'NT AUTHORITY\SYSTEM' have the required permissions, throw an error. + if ( -not $clusterPermissionsPresent ) + { + throw ($script:localizedData.ClusterPermissionsMissing -f $sqlServer,$sqlInstanceName ) + } + + return $clusterPermissionsPresent +} + +<# + .SYNOPSIS + Determine if the current node is hosting the instance. + + .PARAMETER ServerObject + The server object on which to perform the test. +#> +function Test-ActiveNode +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [Microsoft.SqlServer.Management.Smo.Server] + $ServerObject + ) + + $result = $false + + # Determine if this is a failover cluster instance (FCI) + if ( $ServerObject.IsMemberOfWsfcCluster ) + { + <# + If the current node name is the same as the name the instances is + running on, then this is the active node + #> + $result = $ServerObject.ComputerNamePhysicalNetBIOS -eq $env:COMPUTERNAME + } + else + { + <# + This is a standalone instance, therefore the node will always host + the instance. + #> + $result = $true + } + + return $result +} diff --git a/lib/puppet_x/dsc_resources/SqlServerDsc/en-US/SqlServerDscHelper.strings.psd1 b/lib/puppet_x/dsc_resources/SqlServerDsc/en-US/SqlServerDscHelper.strings.psd1 new file mode 100644 index 000000000..91fb4ed91 --- /dev/null +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/en-US/SqlServerDscHelper.strings.psd1 @@ -0,0 +1,148 @@ +# Localized resources for helper module SqlServerDscHelper. + +ConvertFrom-StringData @' + ConnectedToDatabaseEngineInstance = Connected to SQL instance '{0}'. + FailedToConnectToDatabaseEngineInstance = Failed to connect to SQL instance '{0}'. + ConnectedToAnalysisServicesInstance = Connected to Analysis Services instance '{0}'. + FailedToConnectToAnalysisServicesInstance = Failed to connected to Analysis Services instance '{0}'. + SqlMajorVersion = SQL major version is {0}. + CreatingApplicationDomain = Creating application domain '{0}'. + ReusingApplicationDomain = Reusing application domain '{0}'. + LoadingAssembly = Loading assembly '{0}'. + UnloadingApplicationDomain = Unloading application domain '{0}'. + SqlServerVersionIsInvalid = Could not get the SQL version for the instance '{0}'. + PropertyTypeInvalidForDesiredValues = Property 'DesiredValues' must be either a [System.Collections.Hashtable], [CimInstance] or [PSBoundParametersDictionary]. The type detected was {0}. + PropertyTypeInvalidForValuesToCheck = If 'DesiredValues' is a CimInstance, then property 'ValuesToCheck' must contain a value. + PropertyValidationError = Expected to find an array value for property {0} in the current values, but it was either not present or was null. This has caused the test method to return false. + PropertiesDoesNotMatch = Found an array for property {0} in the current values, but this array does not match the desired state. Details of the changes are below. + PropertyThatDoesNotMatch = {0} - {1} + ValueOfTypeDoesNotMatch = {0} value for property {1} does not match. Current state is '{2}' and desired state is '{3}'. + UnableToCompareProperty = Unable to compare property {0} as the type {1} is not handled by the Test-SQLDSCParameterState cmdlet. + PreferredModuleFound = Preferred module SqlServer found. + PreferredModuleNotFound = Information: PowerShell module SqlServer not found, trying to use older SQLPS module. + ImportingPowerShellModule = Importing PowerShell module {0}. + DebugMessagePushingLocation = SQLPS module changes CWD to SQLSERVER:\ when loading, pushing location to pop it when module is loaded. + DebugMessageImportedPowerShellModule = Module {0} imported. + DebugMessagePoppingLocation = Popping location back to what it was before importing SQLPS module. + PowerShellSqlModuleNotFound = Neither PowerShell module SqlServer or SQLPS was found. Unable to run SQL Server cmdlets. + FailedToImportPowerShellSqlModule = Failed to import {0} module. + GetSqlServerClusterResources = Getting cluster resource for SQL Server. + GetSqlAgentClusterResource = Getting active cluster resource SQL Server Agent. + BringClusterResourcesOffline = Bringing the SQL Server resources {0} offline. + BringSqlServerClusterResourcesOnline = Bringing the SQL Server resource back online. + BringSqlServerAgentClusterResourcesOnline = Bringing the SQL Server Agent resource online. + GetServiceInformation = Getting {0} service information. + RestartService = {0} service restarting. + StartingDependentService = Starting service {0} + WaitingInstanceTimeout = Waiting for instance {0}\\{1} to report status online, with a timeout value of {2} seconds. + FailedToConnectToInstanceTimeout = Failed to connect to the instance {0}\\{1} within the timeout period of {2} seconds. + ExecuteQueryWithResultsFailed = Executing query with results failed on database '{0}'. + ExecuteNonQueryFailed = Executing non-query failed on database '{0}'. + AlterAvailabilityGroupReplicaFailed = Failed to alter the availability group replica '{0}'. + GetEffectivePermissionForLogin = Getting the effective permissions for the login '{0}' on '{1}'. + ClusterPermissionsMissing = The cluster does not have permissions to manage the Availability Group on '{0}\\{1}'. Grant 'Connect SQL', 'Alter Any Availability Group', and 'View Server State' to either 'NT SERVICE\\ClusSvc' or 'NT AUTHORITY\\SYSTEM'. + ClusterLoginMissing = The login '{0}' is not present. {1} + ClusterLoginMissingPermissions = The account '{0}' is missing one or more of the following permissions: {1} + ClusterLoginMissingRecommendedPermissions = The recommended account '{0}' is missing one or more of the following permissions: {1} + ClusterLoginPermissionsPresent = The cluster login '{0}' has the required permissions. + + # - NOTE! + # - Below strings are used by helper functions New-TerminatingError and New-WarningMessage. + # - These strings were merged from old SqlServerDsc.strings.psd1. These will be moved to it's individual + # - resource when that resources get moved over to the new localization. + # - NOTE! + + # Common + NoKeyFound = No Localization key found for ErrorType: '{0}'. + AbsentNotImplemented = Ensure = Absent is not implemented! + TestFailedAfterSet = Test-TargetResource returned false after calling set. + RemoteConnectionFailed = Remote PowerShell connection to Server '{0}' failed. + TODO = ToDo. Work not implemented at this time. + UnexpectedErrorFromGet = Got unexpected result from Get-TargetResource. No change is made. + NotConnectedToInstance = Was unable to connect to the instance '{0}\\{1}' + AlterAvailabilityGroupFailed = Failed to alter the availability group '{0}'. + HadrNotEnabled = HADR is not enabled. + AvailabilityGroupNotFound = Unable to locate the availability group '{0}' on the instance '{1}'. + ParameterNotOfType = The parameter '{0}' is not of the type '{1}'. + ParameterNullOrEmpty = The parameter '{0}' is NULL or empty. + + # SQLServer + NoDatabase = Database '{0}' does not exist on SQL server '{1}\\{2}'. + SSRSNotFound = SQL Reporting Services instance '{0}' does not exist! + RoleNotFound = Role '{0}' does not exist on database '{1}' on SQL server '{2}\\{3}'." + LoginNotFound = Login '{0}' does not exist on SQL server '{1}\\{2}'." + FailedLogin = Creating a login of type 'SqlLogin' requires LoginCredential + + # Database Role + AddLoginDatabaseSetError = Failed adding the login {2} as a user of the database {3}, on the instance {0}\\{1}. + DropMemberDatabaseSetError = Failed removing the login {2} from the role {3} on the database {4}, on the instance {0}\\{1}. + AddMemberDatabaseSetError = Failed adding the login {2} to the role {3} on the database {4}, on the instance {0}\\{1}. + + # AvailabilityGroupListener + AvailabilityGroupListenerNotFound = Trying to make a change to a listener that does not exist. + AvailabilityGroupListenerErrorVerifyExist = Unexpected result when trying to verify existence of listener '{0}'. + AvailabilityGroupListenerIPChangeError = IP-address configuration mismatch. Expecting '{0}' found '{1}'. Resource does not support changing IP-address. Listener needs to be removed and then created again. + AvailabilityGroupListenerDHCPChangeError = IP-address configuration mismatch. Expecting '{0}' found '{1}'. Resource does not support changing between static IP and DHCP. Listener needs to be removed and then created again. + + # Endpoint + EndpointNotFound = Endpoint '{0}' does not exist + EndpointErrorVerifyExist = Unexpected result when trying to verify existence of endpoint '{0}'. + EndpointFoundButWrongType = Endpoint '{0}' does exist, but it is not of type 'DatabaseMirroring'. + + # Permission + PermissionGetError = Unexpected result when trying to get permissions for '{0}'. + ChangingPermissionFailed = Changing permission for principal '{0}' failed. + + # AlwaysOnService + AlterAlwaysOnServiceFailed = Failed to ensure Always On is {0} on the instance '{1}'. + UnexpectedAlwaysOnStatus = The status of property Server.IsHadrEnabled was neither $true or $false. Status is '{0}'. + + # Login + PasswordValidationFailed = Creation of the login '{0}' failed due to the following error: {1} + LoginCreationFailedFailedOperation = Creation of the login '{0}' failed due to a failed operation. + LoginCreationFailedSqlNotSpecified = Creation of the SQL login '{0}' failed due to an unspecified error. + LoginCreationFailedWindowsNotSpecified = Creation of the Windows login '{0}' failed due to an unspecified error. + LoginTypeNotImplemented = The login type '{0}' is not implemented in this resource. + IncorrectLoginMode = The instance '{0}\{1}' is currently in '{2}' authentication mode. To create a SQL Login, it must be set to 'Mixed' authentication mode. + LoginCredentialNotFound = The credential for the SQL Login '{0}' was not found. + PasswordChangeFailed = Setting the password failed for the SQL Login '{0}'. + AlterLoginFailed = Altering the login '{0}' failed. + CreateLoginFailed = Creating the login '{0}' failed. + DropLoginFailed = Dropping the login '{0}' failed. + + # AlwaysOnAvailabilityGroup + CreateAvailabilityGroupReplicaFailed = Creating the Availability Group Replica '{0}' failed on the instance '{1}'. + CreateAvailabilityGroupFailed = Creating the availability group '{0}'. + DatabaseMirroringEndpointNotFound = No database mirroring endpoint was found on '{0}\{1}'. + InstanceNotPrimaryReplica = The instance '{0}' is not the primary replica for the availability group '{1}'. + RemoveAvailabilityGroupFailed = Failed to remove the availability group '{0}' from the '{1}' instance. + + # AlwaysOnAvailabilityGroupReplica + JoinAvailabilityGroupFailed = Failed to join the availability group replica '{0}'. + RemoveAvailabilityGroupReplicaFailed = Failed to remove the availability group replica '{0}'. + ReplicaNotFound = Unable to find the availability group replica '{0}' on the instance '{1}'. + + # Max degree of parallelism + MaxDopSetError = Unexpected result when trying to configure the max degree of parallelism server configuration option. + MaxDopParamMustBeNull = MaxDop parameter must be set to $null or not assigned if DynamicAlloc parameter is set to $true. + + # Server Memory + MaxMemoryParamMustBeNull = The parameter MaxMemory must be null when DynamicAlloc is set to true. + MaxMemoryParamMustNotBeNull = The parameter MaxMemory must not be null when DynamicAlloc is set to false. + AlterServerMemoryFailed = Failed to alter the server configuration memory for {0}\\{1}. + ErrorGetDynamicMaxMemory = Failed to calculate dynamically the maximum memory. + + # SQLServerDatabase + CreateDatabaseSetError = Failed to create the database named {2} on {0}\\{1}. + DropDatabaseSetError = Failed to drop the database named {2} on {0}\\{1}. + FailedToGetOwnerDatabase = Failed to get owner of the database named {0} on {1}\\{2}. + FailedToSetOwnerDatabase = Failed to set owner named {0} of the database named {1} on {2}\\{3}. + FailedToSetPermissionDatabase = Failed to set permission for login named {0} of the database named {1} on {2}\\{3}. + FailedToEnumDatabasePermissions = Failed to get permission for login named {0} of the database named {1} on {2}\\{3}. + UpdateDatabaseSetError = Failed to update database {1} on {0}\\{1} with specified changes. + InvalidCollationError = The specified collation '{3}' is not a valid collation for database {2} on {0}\\{1}. + + # SQLServerNetwork + UnableToUseBothDynamicAndStaticPort = Unable to set both TCP dynamic port and TCP static port. Only one can be set. + +'@ diff --git a/lib/puppet_x/dsc_resources/SqlServerDsc/sv-SE/SqlServerDscHelper.strings.psd1 b/lib/puppet_x/dsc_resources/SqlServerDsc/sv-SE/SqlServerDscHelper.strings.psd1 new file mode 100644 index 000000000..987b25b50 --- /dev/null +++ b/lib/puppet_x/dsc_resources/SqlServerDsc/sv-SE/SqlServerDscHelper.strings.psd1 @@ -0,0 +1,144 @@ +# Swedish localized resources for helper module SqlServerDscHelper. + +ConvertFrom-StringData @' + ConnectedToDatabaseEngineInstance = Ansluten till SQL instans '{0}'. + FailedToConnectToDatabaseEngineInstance = Misslyckades att ansluta till SQL instans '{0}'. + ConnectedToAnalysisServicesInstance = Ansluten till Analysis Services instans '{0}'. + FailedToConnectToAnalysisServicesInstance = Misslyckades att ansluta till Analysis Services instans '{0}'. + SqlMajorVersion = SQL major version är {0}. + CreatingApplicationDomain = Skapar applikationsdomän '{0}'. + ReusingApplicationDomain = Återanvänder applikationsdomän '{0}'. + LoadingAssembly = Laddar samling '{0}'. + UnloadingApplicationDomain = Återställer applikationsdomän '{0}'. + SqlServerVersionIsInvalid = Kunde inte hämta SQL version för instansen '{0}'. + PropertyTypeInvalidForDesiredValues = Egenskapen 'DesiredValues' måste vara endera en [System.Collections.Hashtable], [CimInstance] eller [PSBoundParametersDictionary]. Den typ som hittades var {0}. + PropertyTypeInvalidForValuesToCheck = Om 'DesiredValues' är av typ CimInstance, då måste egenskapen 'ValuesToCheck' sättas till ett värde. + PropertyValidationError = Förväntades hitta ett värde av typen matris för egenskapen {0} för nuvarande värden, men den var endera inte tillgänglig eller så var den satt till Null. Detta har medfört att test metoden har retunerat falskt. + PropertiesDoesNotMatch = Hittade en matris för egenskapen {0} för nuvarande värden, men denna matris matchar inte önskat läge. Detaljer för ändringarna finns nedan. + PropertyThatDoesNotMatch = {0} - {1} + ValueOfTypeDoesNotMatch = {0} värde för egenskapen {1} matchar inte. Nuvarande läge är '{2}' och önskat läge är '{3}'. + UnableToCompareProperty = Inte möjligt att jämföra egenskapen {0} som typen {1}. {1} hanteras inte av Test-SQLDscParameterState cmdlet. + PreferredModuleFound = Föredragen modul SqlServer funnen. + PreferredModuleNotFound = Information: PowerShell modul SqlServer ej funnen, försöker att använda äldre SQLPS modul. + ImportingPowerShellModule = Importerar PowerShell modul {0}. + DebugMessagePushingLocation = SQLPS modul ändrar nuvarande katalog till SQLSERVER:\ när modulen laddas, sparar nuvarande katalog så den kan återställas efter modulen laddats. + DebugMessageImportedPowerShellModule = Modul {0} importerad. + DebugMessagePoppingLocation = Återställer nuvarande katalog till vad den var innan modulen SQLPS importerades. + PowerShellSqlModuleNotFound = Varken PowerShell modulen SqlServer eller SQLPS kunde hittas. Kommer inte kunna köra SQL Server cmdlets. + FailedToImportPowerShellSqlModule = Misslyckades att importera {0} modulen. + GetSqlServerClusterResources = Hämtar kluster resurser för SQL Server. + GetSqlAgentClusterResource = Hämtar aktiva kluster resurser för SQL Server Agent. + BringClusterResourcesOffline = Tar SQL Server resurser {0} offline. + BringSqlServerClusterResourcesOnline = Tar SQL Server resurser online igen. + BringSqlServerAgentClusterResourcesOnline = Tar SQL Server Agent resurser online. + GetSqlServerService = Hämtar SQL Server-tjänst information. + RestartSqlServerService = SQL Server-tjänst startar om. + StartingDependentService = Startar tjänst {0} + ExecuteQueryWithResultsFailed = Exekvering av fråga med resultat misslyckades mot databas '{0}'. + ExecuteNonQueryFailed = Exekvering av icke-fråga misslyckades på databas '{0}'. + AlterAvailabilityGroupReplicaFailed = Misslyckades att ändra Availability Group kopia '{0}'. + GetEffectivePermissionForLogin = Hämtar effektiva behörigeter för inloggningen '{0}' på '{1}'. + + # - NOTE! + # - Below strings are used by helper functions New-TerminatingError and New-WarningMessage. + # - These strings were merged from old SqlServerDsc.strings.psd1. These will be moved to it's individual + # - resource when that resources get moved over to the new localization. + # - NOTE! + + # Common + NoKeyFound = No Localization key found for ErrorType: '{0}'. + AbsentNotImplemented = Ensure = Absent is not implemented! + TestFailedAfterSet = Test-TargetResource returned false after calling set. + RemoteConnectionFailed = Remote PowerShell connection to Server '{0}' failed. + TODO = ToDo. Work not implemented at this time. + UnexpectedErrorFromGet = Got unexpected result from Get-TargetResource. No change is made. + NotConnectedToInstance = Was unable to connect to the instance '{0}\\{1}' + AlterAvailabilityGroupFailed = Failed to alter the availability group '{0}'. + HadrNotEnabled = HADR is not enabled. + AvailabilityGroupNotFound = Unable to locate the availability group '{0}' on the instance '{1}'. + ParameterNotOfType = The parameter '{0}' is not of the type '{1}'. + ParameterNullOrEmpty = The parameter '{0}' is NULL or empty. + + # SQLServer + NoDatabase = Database '{0}' does not exist on SQL server '{1}\\{2}'. + SSRSNotFound = SQL Reporting Services instance '{0}' does not exist! + RoleNotFound = Role '{0}' does not exist on database '{1}' on SQL server '{2}\\{3}'." + LoginNotFound = Login '{0}' does not exist on SQL server '{1}\\{2}'." + FailedLogin = Creating a login of type 'SqlLogin' requires LoginCredential + + # Database Role + AddLoginDatabaseSetError = Failed adding the login {2} as a user of the database {3}, on the instance {0}\\{1}. + DropMemberDatabaseSetError = Failed removing the login {2} from the role {3} on the database {4}, on the instance {0}\\{1}. + AddMemberDatabaseSetError = Failed adding the login {2} to the role {3} on the database {4}, on the instance {0}\\{1}. + + # AvailabilityGroupListener + AvailabilityGroupListenerNotFound = Trying to make a change to a listener that does not exist. + AvailabilityGroupListenerErrorVerifyExist = Unexpected result when trying to verify existence of listener '{0}'. + AvailabilityGroupListenerIPChangeError = IP-address configuration mismatch. Expecting '{0}' found '{1}'. Resource does not support changing IP-address. Listener needs to be removed and then created again. + AvailabilityGroupListenerDHCPChangeError = IP-address configuration mismatch. Expecting '{0}' found '{1}'. Resource does not support changing between static IP and DHCP. Listener needs to be removed and then created again. + + # Endpoint + EndpointNotFound = Endpoint '{0}' does not exist + EndpointErrorVerifyExist = Unexpected result when trying to verify existence of endpoint '{0}'. + EndpointFoundButWrongType = Endpoint '{0}' does exist, but it is not of type 'DatabaseMirroring'. + + # Permission + PermissionGetError = Unexpected result when trying to get permissions for '{0}'. + ChangingPermissionFailed = Changing permission for principal '{0}' failed. + + # Configuration + ConfigurationOptionNotFound = Specified option '{0}' could not be found. + ConfigurationRestartRequired = Configuration option '{0}' has been updated, but a manual restart of SQL Server is required for it to take effect. + + # AlwaysOnService + AlterAlwaysOnServiceFailed = Failed to ensure Always On is {0} on the instance '{1}'. + UnexpectedAlwaysOnStatus = The status of property Server.IsHadrEnabled was neither $true or $false. Status is '{0}'. + + # Login + PasswordValidationFailed = Creation of the login '{0}' failed due to the following error: {1} + LoginCreationFailedFailedOperation = Creation of the login '{0}' failed due to a failed operation. + LoginCreationFailedSqlNotSpecified = Creation of the SQL login '{0}' failed due to an unspecified error. + LoginCreationFailedWindowsNotSpecified = Creation of the Windows login '{0}' failed due to an unspecified error. + LoginTypeNotImplemented = The login type '{0}' is not implemented in this resource. + IncorrectLoginMode = The instance '{0}\{1}' is currently in '{2}' authentication mode. To create a SQL Login, it must be set to 'Mixed' authentication mode. + LoginCredentialNotFound = The credential for the SQL Login '{0}' was not found. + PasswordChangeFailed = Setting the password failed for the SQL Login '{0}'. + AlterLoginFailed = Altering the login '{0}' failed. + CreateLoginFailed = Creating the login '{0}' failed. + DropLoginFailed = Dropping the login '{0}' failed. + + # AlwaysOnAvailabilityGroup + ClusterPermissionsMissing = The cluster does not have permissions to manage the Availability Group on '{0}\\{1}'. Grant 'Connect SQL', 'Alter Any Availability Group', and 'View Server State' to either 'NT SERVICE\\ClusSvc' or 'NT AUTHORITY\\SYSTEM'. + CreateAvailabilityGroupReplicaFailed = Creating the Availability Group Replica '{0}' failed on the instance '{1}'. + CreateAvailabilityGroupFailed = Creating the availability group '{0}'. + DatabaseMirroringEndpointNotFound = No database mirroring endpoint was found on '{0}\{1}'. + InstanceNotPrimaryReplica = The instance '{0}' is not the primary replica for the availability group '{1}'. + RemoveAvailabilityGroupFailed = Failed to remove the availability group '{0}' from the '{1}' instance. + + # AlwaysOnAvailabilityGroupReplica + JoinAvailabilityGroupFailed = Failed to join the availability group replica '{0}'. + RemoveAvailabilityGroupReplicaFailed = Failed to remove the availability group replica '{0}'. + ReplicaNotFound = Unable to find the availability group replica '{0}' on the instance '{1}'. + + # Max degree of parallelism + MaxDopSetError = Unexpected result when trying to configure the max degree of parallelism server configuration option. + MaxDopParamMustBeNull = MaxDop parameter must be set to $null or not assigned if DynamicAlloc parameter is set to $true. + + # Server Memory + MaxMemoryParamMustBeNull = The parameter MaxMemory must be null when DynamicAlloc is set to true. + MaxMemoryParamMustNotBeNull = The parameter MaxMemory must not be null when DynamicAlloc is set to false. + AlterServerMemoryFailed = Failed to alter the server configuration memory for {0}\\{1}. + ErrorGetDynamicMaxMemory = Failed to calculate dynamically the maximum memory. + + # SQLServerDatabase + CreateDatabaseSetError = Failed to create the database named {2} on {0}\\{1}. + DropDatabaseSetError = Failed to drop the database named {2} on {0}\\{1}. + FailedToGetOwnerDatabase = Failed to get owner of the database named {0} on {1}\\{2}. + FailedToSetOwnerDatabase = Failed to set owner named {0} of the database named {1} on {2}\\{3}. + FailedToSetPermissionDatabase = Failed to set permission for login named {0} of the database named {1} on {2}\\{3}. + FailedToEnumDatabasePermissions = Failed to get permission for login named {0} of the database named {1} on {2}\\{3}. + + # SQLServerNetwork + UnableToUseBothDynamicAndStaticPort = Unable to set both TCP dynamic port and TCP static port. Only one can be set. + +'@ diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLAOGroupEnsure/MSFT_xSQLAOGroupEnsure.psm1 b/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLAOGroupEnsure/MSFT_xSQLAOGroupEnsure.psm1 deleted file mode 100644 index f9c07c7f0..000000000 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLAOGroupEnsure/MSFT_xSQLAOGroupEnsure.psm1 +++ /dev/null @@ -1,367 +0,0 @@ -$currentPath = Split-Path -Parent $MyInvocation.MyCommand.Path -Write-Verbose -Message "CurrentPath: $currentPath" - -Import-Module $currentPath\..\..\xSQLServerHelper.psm1 -Verbose:$false -ErrorAction Stop - -function Get-TargetResource -{ - [CmdletBinding()] - [OutputType([System.Collections.Hashtable])] - param - ( - [parameter(Mandatory = $true)] - [ValidateSet('Present','Absent')] - [System.String] - $Ensure, - - [parameter(Mandatory = $true)] - [System.String] - $AvailabilityGroupName, - - [System.String] - $SQLServer = $env:COMPUTERNAME, - - [ValidateNotNull()] - [System.String] - $SQLInstanceName= 'MSSQLSERVER', - - [parameter(Mandatory = $true)] - [System.Management.Automation.PSCredential] - $SetupCredential - ) - - $sql = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName -SetupCredential $SetupCredential - - $vConfigured = Test-TargetResource -Ensure $Ensure -AvailabilityGroupName $AvailabilityGroupName -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName -SetupCredential $SetupCredential - - $returnValue = @{ - Ensure = $vConfigured - AvailabilityGroupName = $sql.AvailabilityGroups[$AvailabilityGroupName] - AvailabilityGroupNameListener = $sql.AvailabilityGroups[$AvailabilityGroupName].AvailabilityGroupListeners.name - AvailabilityGroupNameIP = $sql.AvailabilityGroups[$AvailabilityGroupName].AvailabilityGroupListeners.availabilitygrouplisteneripaddresses.IPAddress - AvailabilityGroupSubMask = $sql.AvailabilityGroups[$AvailabilityGroupName].AvailabilityGroupListeners.availabilitygrouplisteneripaddresses.SubnetMask - AvailabilityGroupPort = $sql.AvailabilityGroups[$AvailabilityGroupName].AvailabilityGroupListeners.portnumber - AvailabilityGroupNameDatabase = $sql.AvailabilityGroups[$AvailabilityGroupName].AvailabilityDatabases.name - BackupDirectory = '' - SQLServer = $SQLServer - SQLInstanceName = $SQLInstanceName - } - - $returnValue -} - -function Set-TargetResource -{ - [CmdletBinding()] - param - ( - [parameter(Mandatory = $true)] - [ValidateSet('Present', 'Absent')] - [System.String] - $Ensure, - - [parameter(Mandatory = $true)] - [System.String] - $AvailabilityGroupName, - - [System.String] - $AvailabilityGroupNameListener = $AvailabilityGroupName, - - [System.String[]] - $AvailabilityGroupNameIP, - - [System.String[]] - $AvailabilityGroupSubMask, - - [System.UInt32] - $AvailabilityGroupPort = '1433', - - [ValidateSet('None', 'ReadOnly', 'ReadIntent')] - [System.String] - $ReadableSecondary = 'ReadOnly', - - [ValidateSet('Primary', 'Secondary')] - [System.String] - $AutoBackupPreference = 'Primary', - - [System.UInt32] - $BackupPriority = '50', - - [System.UInt32] - $EndPointPort = '5022', - - [System.String] - $SQLServer = $env:COMPUTERNAME, - - [System.String] - $SQLInstanceName = 'MSSQLSERVER', - - [parameter(Mandatory = $true)] - [System.Management.Automation.PSCredential] - $SetupCredential - ) - - $null = [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.Smo') - $null = [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SmoExtended') - - $sql = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName -SetupCredential $SetupCredential - - if (($AvailabilityGroupNameIP -and !$AvailabilityGroupSubMask) -or (!$AvailabilityGroupNameIP -and $AvailabilityGroupSubMask)) - { - throw 'AvailabilityGroupNameIP and AvailabilityGroupSubMask must both be passed for Static IP assignment.' - } - - switch ($Ensure) - { - 'Present' - { - Grant-ServerPerms -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName -AuthorizedUser 'NT AUTHORITY\SYSTEM' -SetupCredential $SetupCredential - New-ListenerADObject -AvailabilityGroupNameListener $AvailabilityGroupNameListener -SetupCredential $SetupCredential -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName - - $FailoverCondition = 3 - $HealthCheckTimeout = 30000 - $ConnectionModeInPrimary = 'AllowAllConnections' - - $ConnectionModeInSecondaryRole = switch ($ReadableSecondary) - { - 'None' - { - 'AllowNoConnections' - } - - 'ReadOnly' - { - 'AllowAllConnections' - } - - 'ReadIntent' - { - 'AllowReadIntentConnectionsOnly' - } - - Default - { - 'AllowAllConnections' - } - } - - # Get Servers participating in the cluster - # First two nodes will account for Syncronous Automatic Failover, Any additional will be Asyncronous - try - { - $nodes = Get-ClusterNode -cluster $sql.ClusterName -Verbose:$false | Select-Object -ExpandProperty name - $syncNodes = $nodes | Select-Object -First 2 - $asyncNodes = $nodes | Select-Object -Skip 2 - $availabilityGroup = New-Object -typename Microsoft.SqlServer.Management.Smo.AvailabilityGroup -ArgumentList $SQL, $AvailabilityGroupName - $availabilityGroup.AutomatedBackupPreference = $AutoBackupPreference - $availabilityGroup.FailureConditionLevel = $FailoverCondition - $availabilityGroup.HealthCheckTimeout = $HealthCheckTimeout - } - catch - { - throw "Failed to connect to Cluster Nodes from $($sql.ClusterName)" - } - - # Loop through Sync nodes Create Replica Object Assign properties and add it to AvailabilityGroup - foreach ($node in $syncNodes) - { - Try - { - $Replica = New-Object -typename Microsoft.SqlServer.Management.Smo.AvailabilityReplica -ArgumentList $availabilityGroup, $node - $Replica.EndpointUrl = "TCP://$($node):$EndPointPort" - $Replica.FailoverMode = [Microsoft.SqlServer.Management.Smo.AvailabilityReplicaFailoverMode]::Automatic - $Replica.AvailabilityMode = [Microsoft.SqlServer.Management.Smo.AvailabilityReplicaAvailabilityMode]::SynchronousCommit - # Backup Priority Gives the ability to set a priority of one secondany over another valid values are from 1 - 100 - $Replica.BackupPriority = $BackupPriority - $Replica.ConnectionModeInPrimaryRole = $ConnectionModeInPrimary - $replica.ConnectionModeInSecondaryRole = $ConnectionModeInSecondaryRole - $availabilityGroup.AvailabilityReplicas.Add($Replica) - } - catch - { - throw "Failed to add $Replica to the Availability Group $AvailabilityGroupName" - } - } - - # Loop through ASync nodes Create Replica Object Assign properties and add it to AvailabilityGroup - foreach ($node in $AsyncNodes) - { - try - { - $asyncReplica = New-Object -typename Microsoft.SqlServer.Management.Smo.AvailabilityReplica -ArgumentList $availabilityGroup, $node - $asyncReplica.EndpointUrl = "TCP://$($node):$EndPointPort" - $asyncReplica.FailoverMode = [Microsoft.SqlServer.Management.Smo.AvailabilityReplicaFailoverMode]::Manual - $asyncReplica.AvailabilityMode = [Microsoft.SqlServer.Management.Smo.AvailabilityReplicaAvailabilityMode]::ASynchronousCommit - $asyncReplica.BackupPriority = $BackupPriority - $asyncReplica.ConnectionModeInPrimaryRole = $ConnectionModeInPrimary - $asyncReplica.ConnectionModeInSecondaryRole = $ConnectionModeInSecondaryRole - $AvailabilityGroup.AvailabilityReplicas.Add($asyncReplica) - } - catch - { - Write-Error "Failed to add $asyncReplica to the Availability Group $AvailabilityGroupName" - } - } - - try - { - $AgListener = New-Object -typename Microsoft.SqlServer.Management.Smo.AvailabilityGroupListener -ArgumentList $AvailabilityGroup, $AvailabilityGroupNameListener - $AgListener.PortNumber =$AvailabilityGroupPort - } - catch - { - Write-Error -Message ('{0}: Failed to Create AG Listener Object' -f ((Get-Date -format yyyy-MM-dd_HH-mm-ss))) - } - - - if ($AvailabilityGroupNameIP) - { - foreach ($IP in $AvailabilityGroupNameIP) - { - $AgListenerIp = New-Object -typename Microsoft.SqlServer.Management.Smo.AvailabilityGroupListenerIPAddress -ArgumentList $AgListener - $AgListenerIp.IsDHCP = $false - $AgListenerIp.IPAddress = $IP - $AgListenerIp.SubnetMask = $AvailabilityGroupSubMask - $AgListener.AvailabilityGroupListenerIPAddresses.Add($AgListenerIp) - New-VerboseMessage -Message "Added Static IP $IP to $AvailabilityGroupNameListener..." - - } - } - else - { - # Utilize Dynamic IP since no Ip was passed - $AgListenerIp = New-Object -typename Microsoft.SqlServer.Management.Smo.AvailabilityGroupListenerIPAddress -ArgumentList $AgListener - $AgListenerIp.IsDHCP = $true - $AgListener.AvailabilityGroupListenerIPAddresses.Add($AgListenerIp) - New-VerboseMessage -Message "Added DynamicIP to $AvailabilityGroupNameListener..." - } - - try - { - $AvailabilityGroup.AvailabilityGroupListeners.Add($AgListener); - } - catch - { - throw "Failed to Add $AvailabilityGroupNameListener to $AvailabilityGroupName..." - } - - # Add Availabilty Group to the SQL connection - try - { - $SQL.AvailabilityGroups.Add($availabilityGroup) - New-VerboseMessage -Message "Added $availabilityGroupName Availability Group to Connection" - } - catch - { - throw "Unable to Add $AvailabilityGroup to $SQLServer\$SQLInstanceName" - } - - # Create Availability Group - try - { - $availabilityGroup.Create() - - New-VerboseMessage -Message "Created Availability Group $availabilityGroupName" - } - catch - { - throw "Unable to Create $AvailabilityGroup on $SQLServer\$SQLInstanceName" - } - } - - 'Absent' - { - try - { - $sql.AvailabilityGroups[$AvailabilityGroupName].Drop() - - New-VerboseMessage -Message "Dropped $AvailabilityGroupName" - } - catch - { - throw "Unable to Drop $AvailabilityGroup on $SQLServer\$SQLInstanceName" - } - } - } -} - -function Test-TargetResource -{ - [CmdletBinding()] - [OutputType([System.Boolean])] - param - ( - [parameter(Mandatory = $true)] - [ValidateSet('Present', 'Absent')] - [System.String] - $Ensure, - - [parameter(Mandatory = $true)] - [System.String] - $AvailabilityGroupName, - - [System.String] - $AvailabilityGroupNameListener, - - [System.String[]] - $AvailabilityGroupNameIP, - - [System.String[]] - $AvailabilityGroupSubMask, - - [System.UInt32] - $AvailabilityGroupPort, - - [ValidateSet('None', 'ReadOnly', 'ReadIntent')] - [System.String] - $ReadableSecondary ='ReadOnly', - - [ValidateSet('Primary', 'Secondary')] - [System.String] - $AutoBackupPreference = 'Primary', - - [System.UInt32] - $BackupPriority = '50', - - [System.UInt32] - $EndPointPort = '5022', - - [System.String] - $SQLServer = $env:COMPUTERNAME, - - [System.String] - $SQLInstanceName = 'MSSQLSERVER', - - [parameter(Mandatory = $true)] - [System.Management.Automation.PSCredential] - $SetupCredential - ) - - $sql = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName -SetupCredential $SetupCredential - - $result = $false - - switch ($Ensure) - { - 'Present' - { - $availabilityGroupPresent = $sql.AvailabilityGroups.Contains($AvailabilityGroupName) - if ($availabilityGroupPresent) - { - $result = $true - } - } - - 'Absent' - { - if (!$sql.AvailabilityGroups[$AvailabilityGroupName]) - { - $result = $true - } - } - } - - return $result -} - -Export-ModuleMember -Function *-TargetResource diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLAOGroupEnsure/MSFT_xSQLAOGroupEnsure.schema.mof b/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLAOGroupEnsure/MSFT_xSQLAOGroupEnsure.schema.mof deleted file mode 100644 index 0d722dd6b..000000000 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLAOGroupEnsure/MSFT_xSQLAOGroupEnsure.schema.mof +++ /dev/null @@ -1,17 +0,0 @@ -[ClassVersion("1.0.0.0"), FriendlyName("xSQLAOGroupEnsure")] -class MSFT_xSQLAOGroupEnsure : OMI_BaseResource -{ - [Key, Description("Determines whether the availability group should be added or removed."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; - [Key, Description("Name for availability group.")] String AvailabilityGroupName; - [Write, Description("Listener name for availability group.")] String AvailabilityGroupNameListener; - [Write, Description("List of IP addresses associated with listener.")] String AvailabilityGroupNameIP[]; - [Write, Description("Network subnetmask for listener.")] String AvailabilityGroupSubMask[]; - [Write, Description("Port availability group should listen on.")] Uint32 AvailabilityGroupPort; - [Write, Description("Mode secondaries should operate under (None, ReadOnly, ReadIntent)."), ValueMap{"None","ReadOnly","ReadIntent"}, Values{"None","ReadOnly","ReadIntent"}] String ReadableSecondary; - [Write, Description("Where backups should be backed up from (Primary, Secondary)."), ValueMap{"Primary","Secondary"}, Values{"Primary","Secondary"}] String AutoBackupPreference; - [Write, Description("The percentage weight for backup prority (default 50).")] Uint32 BackupPriority; - [Write, Description("he TCP port for the SQL AG Endpoint (default 5022).")] Uint32 EndPointPort; - [Write, Description("The SQL Server for the database.")] String SQLServer; - [Write, Description("The SQL instance for the database.")] String SQLInstanceName; - [Required, EmbeddedInstance("MSFT_Credential"), Description("Credential to be used to Grant Permissions on SQL Server, set this to $null to use Windows Authentication.")] String SetupCredential; -}; diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLAOGroupJoin/MSFT_xSQLAOGroupJoin.psm1 b/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLAOGroupJoin/MSFT_xSQLAOGroupJoin.psm1 deleted file mode 100644 index a9693ab03..000000000 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLAOGroupJoin/MSFT_xSQLAOGroupJoin.psm1 +++ /dev/null @@ -1,227 +0,0 @@ -$script:currentPath = Split-Path -Path $MyInvocation.MyCommand.Path -Parent -Import-Module -Name (Join-Path -Path (Split-Path -Path (Split-Path -Path $script:currentPath -Parent) -Parent) -ChildPath 'xSQLServerHelper.psm1') - -<# - .SYNOPSIS - Returns the current joined state of the Availability Group. - - .PARAMETER Ensure - If the replica should be joined ('Present') to the Availability Group or not joined ('Absent') to the Availability Group. - - .PARAMETER AvailabilityGroupName - The name Availability Group to join. - - .PARAMETER SQLServer - Name of the SQL server to be configured. - - .PARAMETER SQLInstanceName - Name of the SQL instance to be configured. - - .PARAMETER SetupCredential - Credential to be used to Grant Permissions in SQL. -#> -function Get-TargetResource -{ - [CmdletBinding()] - [OutputType([System.Collections.Hashtable])] - param - ( - [Parameter(Mandatory = $true)] - [ValidateSet('Present','Absent')] - [System.String] - $Ensure, - - [Parameter(Mandatory = $true)] - [System.String] - $AvailabilityGroupName, - - [Parameter()] - [System.String] - $SQLServer = $env:COMPUTERNAME, - - [Parameter()] - [System.String] - $SQLInstanceName= 'MSSQLSERVER', - - [Parameter(Mandatory = $true)] - [System.Management.Automation.PSCredential] - $SetupCredential - ) - - $sql = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName -SetupCredential $SetupCredential - - if (Test-TargetResource @PSBoundParameters) - { - $ensure = 'Present' - } - else - { - $ensure = 'Absent' - } - - return @{ - Ensure = $ensure - AvailabilityGroupName = $sql.AvailabilityGroups[$AvailabilityGroupName].Name - AvailabilityGroupNameListener = $sql.AvailabilityGroups[$AvailabilityGroupName].AvailabilityGroupListeners.Name - AvailabilityGroupNameIP = $sql.AvailabilityGroups[$AvailabilityGroupName].AvailabilityGroupListeners.AvailabilityGroupListenerIPAddresses.IPAddress - AvailabilityGroupSubMask = $sql.AvailabilityGroups[$AvailabilityGroupName].AvailabilityGroupListeners.AvailabilityGroupListenerIPAddresses.SubnetMask - AvailabilityGroupPort = $sql.AvailabilityGroups[$AvailabilityGroupName].AvailabilityGroupListeners.PortNumber - AvailabilityGroupNameDatabase = $sql.AvailabilityGroups[$AvailabilityGroupName].AvailabilityDatabases.Name - BackupDirectory = "" - SQLServer = $SQLServer - SQLInstanceName = $SQLInstanceName - } -} - -<# - .SYNOPSIS - Join the node to the the Availability Group. - - .PARAMETER Ensure - If the replica should be joined ('Present') to the Availability Group or not joined ('Absent') to the Availability Group. - - .PARAMETER AvailabilityGroupName - The name Availability Group to join. - - .PARAMETER SQLServer - Name of the SQL server to be configured. - - .PARAMETER SQLInstanceName - Name of the SQL instance to be configured. - - .PARAMETER SetupCredential - Credential to be used to Grant Permissions in SQL. -#> -function Set-TargetResource -{ - [CmdletBinding()] - param - ( - [Parameter(Mandatory = $true)] - [ValidateSet('Present','Absent')] - [System.String] - $Ensure, - - [Parameter(Mandatory = $true)] - [System.String] - $AvailabilityGroupName, - - [Parameter()] - [System.String] - $SQLServer = $env:COMPUTERNAME, - - [Parameter()] - [System.String] - $SQLInstanceName= 'MSSQLSERVER', - - [Parameter(Mandatory = $true)] - [System.Management.Automation.PSCredential] - $SetupCredential - ) - - Initialize-SqlServerAssemblies - - $sql = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName -SetupCredential $SetupCredential - Grant-ServerPerms -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName -AuthorizedUser "NT AUTHORITY\SYSTEM" -SetupCredential $SetupCredential - - try - { - $sql.JoinAvailabilityGroup($AvailabilityGroupName) - New-VerboseMessage -Message "Joined $SQLServer\$SQLInstanceName to $AvailabilityGroupName" - } - catch - { - throw "Unable to Join $AvailabilityGroupName on $SQLServer\$SQLInstanceName" - } -} - -<# - .SYNOPSIS - Test if the node is joined to the Availability Group. - - .PARAMETER Ensure - If the replica should be joined ('Present') to the Availability Group or not joined ('Absent') to the Availability Group. - - .PARAMETER AvailabilityGroupName - The name Availability Group to join. - - .PARAMETER SQLServer - Name of the SQL server to be configured. - - .PARAMETER SQLInstanceName - Name of the SQL instance to be configured. - - .PARAMETER SetupCredential - Credential to be used to Grant Permissions in SQL. -#> -function Test-TargetResource -{ - [CmdletBinding()] - [OutputType([System.Boolean])] - param - ( - [Parameter(Mandatory = $true)] - [ValidateSet('Present','Absent')] - [System.String] - $Ensure, - - [Parameter(Mandatory = $true)] - [System.String] - $AvailabilityGroupName, - - [Parameter()] - [System.String] - $SQLServer = $env:COMPUTERNAME, - - [Parameter()] - [System.String] - $SQLInstanceName= 'MSSQLSERVER', - - [Parameter(Mandatory = $true)] - [System.Management.Automation.PSCredential] - $SetupCredential - ) - - $sql = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName -SetupCredential $SetupCredential - - $returnValue = $false - - switch ($Ensure) - { - 'Present' - { - $availabilityGroupPresent = $sql.AvailabilityGroups.Contains($AvailabilityGroupName) - - if ($availabilityGroupPresent) - { - $returnValue = $true - } - } - - "Absent" - { - $availabilityGroupPresent = $sql.AvailabilityGroups.Contains($AvailabilityGroupName) - - if (!$availabilityGroupPresent) - { - $returnValue = $true - } - } - } - - return $returnValue -} - -<# - .SYNOPSIS - Loads the needed assemblies for the resource to be able to use methods. -#> -function Initialize-SqlServerAssemblies -{ - param () - - $null = [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.Smo') - $null = [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SmoExtended") -} - -Export-ModuleMember -Function *-TargetResource diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLAOGroupJoin/MSFT_xSQLAOGroupJoin.schema.mof b/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLAOGroupJoin/MSFT_xSQLAOGroupJoin.schema.mof deleted file mode 100644 index c3a19b5e1..000000000 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLAOGroupJoin/MSFT_xSQLAOGroupJoin.schema.mof +++ /dev/null @@ -1,10 +0,0 @@ -[ClassVersion("1.0.0.0"), FriendlyName("xSQLAOGroupJoin")] -class MSFT_xSQLAOGroupJoin : OMI_BaseResource -{ - [Key, Description("If the replica should be joined ('Present') to the Availability Group or not joined ('Absent') to the Availability Group."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; - [Key, Description("The name Availability Group to join.")] String AvailabilityGroupName; - [Write, Description("Name of the SQL server to be configured.")] String SQLServer; - [Write, Description("Name of the SQL instance to be configured.")] String SQLInstanceName; - [Required, EmbeddedInstance("MSFT_Credential"), Description("Credential to be used to Grant Permissions in SQL.")] String SetupCredential; -}; - diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAlwaysOnService/MSFT_xSQLServerAlwaysOnService.psm1 b/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAlwaysOnService/MSFT_xSQLServerAlwaysOnService.psm1 deleted file mode 100644 index 85f074265..000000000 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAlwaysOnService/MSFT_xSQLServerAlwaysOnService.psm1 +++ /dev/null @@ -1,186 +0,0 @@ -Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) ` - -ChildPath 'xSQLServerHelper.psm1') ` - -Force - -<# - .SYNOPSIS - Gets the current value of the SQL Server HADR property. - - .PARAMETER Ensure - *** Not used in this function *** - HADR is Present (enabled) or Absent (disabled). - - .PARAMETER SQLServer - Hostname of the SQL Server to be configured. - - .PARAMETER SQLInstanceName - Name of the SQL instance to be configued. -#> -function Get-TargetResource -{ - [CmdletBinding()] - [OutputType([Hashtable])] - param - ( - [Parameter(Mandatory = $true)] - [ValidateSet('Present','Absent')] - [System.String] - $Ensure, - - [Parameter(Mandatory = $true)] - [System.String] - $SQLServer, - - [Parameter(Mandatory = $true)] - [System.String] - $SQLInstanceName - ) - - $sql = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName - - New-VerboseMessage -Message ( 'SQL Always On is {0} on "{1}\{2}".' -f @{$false='disabled'; $true='enabled'}[$sql.IsHadrEnabled],$SQLServer,$SQLInstanceName ) - - return @{ IsHadrEnabled = $sql.IsHadrEnabled } -} - -<# - .SYNOPSIS - Sets the current value of the SQL Server HADR property. - - .PARAMETER Ensure - HADR is Present (enabled) or Absent (disabled). - - .PARAMETER SQLServer - Hostname of the SQL Server to be configured. - - .PARAMETER SQLInstanceName - Name of the SQL instance to be configued. - - .PARAMETER RestartTimeout - The length of time, in seconds, to wait for the service to restart. Default is 120 seconds. -#> -function Set-TargetResource -{ - [CmdletBinding()] - param - ( - [Parameter(Mandatory = $true)] - [ValidateSet('Present','Absent')] - [System.String] - $Ensure, - - [Parameter(Mandatory = $true)] - [System.String] - $SQLServer, - - [Parameter(Mandatory = $true)] - [System.String] - $SQLInstanceName, - - [Parameter()] - [Int32] - $RestartTimeout = 120 - ) - - # Build the instance name to allow the Enable/Disable-AlwaysOn to connect to the instance - if($SQLInstanceName -eq "MSSQLSERVER") - { - $serverInstance = $SQLServer - } - else - { - $serverInstance = "$SQLServer\$SQLInstanceName" - } - - Import-SQLPSModule - - switch ($Ensure) - { - 'Absent' - { - # Disable Always On without restarting the services. - New-VerboseMessage -Message "Disabling Always On for the instance $serverInstance" - Disable-SqlAlwaysOn -ServerInstance $serverInstance -NoServiceRestart - } - 'Present' - { - # Enable Always On without restarting the services. - New-VerboseMessage -Message "Enabling Always On for the instance $serverInstance" - Enable-SqlAlwaysOn -ServerInstance $serverInstance -NoServiceRestart - } - } - - New-VerboseMessage -Message ( 'SQL Always On has been {0} on "{1}\{2}". Restarting the service.' -f @{Absent='disabled'; Present='enabled'}[$Ensure],$SQLServer,$SQLInstanceName ) - - # Now restart the SQL service so that all dependent services are also returned to their previous state - Restart-SqlService -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName -Timeout $RestartTimeout - - # Verify always on was set - if( -not ( Test-TargetResource @PSBoundParameters ) ) - { - throw New-TerminatingError -ErrorType AlterAlwaysOnServiceFailed -FormatArgs $Ensure,$serverInstance -ErrorCategory InvalidResult - } -} - -<# - .SYNOPSIS - Determines whether the current value of the SQL Server HADR property is properly set. - - .PARAMETER Ensure - HADR is Present (enabled) or Absent (disabled). - - .PARAMETER SQLServer - Hostname of the SQL Server to be configured. - - .PARAMETER SQLInstanceName - Name of the SQL instance to be configued. - - .PARAMETER RestartTimeout - *** Not used in this function *** - The length of time, in seconds, to wait for the service to restart. Default is 120 seconds. -#> -function Test-TargetResource -{ - [CmdletBinding()] - [OutputType([Boolean])] - param - ( - [parameter(Mandatory = $true)] - [ValidateSet('Present','Absent')] - [System.String] - $Ensure, - - [Parameter(Mandatory = $true)] - [System.String] - $SQLServer, - - [Parameter(Mandatory = $true)] - [System.String] - $SQLInstanceName, - - [Parameter()] - [Int32] - $RestartTimeout = 120 - ) - - # Determine the current state of Always On - $params = @{ - Ensure = $Ensure - SQLServer = $SQLServer - SQLInstanceName = $SQLInstanceName - } - - $state = Get-TargetResource @params - - # Determine what the desired state of Always On is - $hadrDesiredState = @{ 'Present' = $true; 'Absent' = $false }[$Ensure] - - # Determine whether the value matches the desired state - $desiredStateMet = $state.IsHadrEnabled -eq $hadrDesiredState - - New-VerboseMessage -Message ( 'SQL Always On is in the desired state for "{0}\{1}": {2}.' -f $SQLServer,$SQLInstanceName,$desiredStateMet ) - - return $desiredStateMet -} - -Export-ModuleMember -Function *-TargetResource diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAlwaysOnService/MSFT_xSQLServerAlwaysOnService.schema.mof b/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAlwaysOnService/MSFT_xSQLServerAlwaysOnService.schema.mof deleted file mode 100644 index 083ef2a04..000000000 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerAlwaysOnService/MSFT_xSQLServerAlwaysOnService.schema.mof +++ /dev/null @@ -1,8 +0,0 @@ -[ClassVersion("1.0.0.0"), FriendlyName("xSQLServerAlwaysOnService")] -class MSFT_xSQLServerAlwaysOnService : OMI_BaseResource -{ - [Required, Description("HADR is Present (enabled) or Absent (disabled)"), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; - [Key, Description("The hostname of the SQL Server to be configured")] String SQLServer; - [Key, Description("Name of the SQL instance to be configured.")] String SQLInstanceName; - [Write, Description("The length of time, in seconds, to wait for the service to restart. Default is 120 seconds.")] Sint32 RestartTimeout; -}; diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerConfiguration/MSFT_xSQLServerConfiguration.psm1 b/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerConfiguration/MSFT_xSQLServerConfiguration.psm1 deleted file mode 100644 index 4a6467246..000000000 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerConfiguration/MSFT_xSQLServerConfiguration.psm1 +++ /dev/null @@ -1,213 +0,0 @@ -# Load Common Code -Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) ` - -ChildPath 'xSQLServerHelper.psm1') ` - -Force -<# - .SYNOPSIS - Gets the current value of a SQL configuration option - - .PARAMETER SQLServer - Hostname of the SQL Server to be configured - - .PARAMETER SQLInstanceName - Name of the SQL instance to be configued. Default is 'MSSQLSERVER' - - .PARAMETER OptionName - The name of the SQL configuration option to be checked - - .PARAMETER OptionValue - The desired value of the SQL configuration option - - .PARAMETER RestartService - *** Not used in this function *** - Determines whether the instance should be restarted after updating the configuration option. - - .PARAMETER RestartTimeout - *** Not used in this function *** - The length of time, in seconds, to wait for the service to restart. Default is 120 seconds. -#> -function Get-TargetResource -{ - [CmdletBinding()] - [OutputType([Hashtable])] - param( - [Parameter(Mandatory = $true)] - [String] - $SQLServer, - - [Parameter(Mandatory = $true)] - [String] - $SQLInstanceName, - - [Parameter(Mandatory = $true)] - [String] - $OptionName, - - [Parameter(Mandatory = $true)] - [Int32] - $OptionValue, - - [Boolean] - $RestartService = $false, - - [Int32] - $RestartTimeout = 120 - ) - - $sql = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName - - ## get the configuration option - $option = $sql.Configuration.Properties | Where-Object { $_.DisplayName -eq $OptionName } - - if(!$option) - { - throw New-TerminatingError -ErrorType "ConfigurationOptionNotFound" -FormatArgs $OptionName -ErrorCategory InvalidArgument - } - - return @{ - SqlServer = $SQLServer - SQLInstanceName = $SQLInstanceName - OptionName = $option.DisplayName - OptionValue = $option.ConfigValue - RestartService = $RestartService - RestartTimeout = $RestartTimeout - } -} - -<# - .SYNOPSIS - Sets the value of a SQL configuration option - - .PARAMETER SQLServer - Hostname of the SQL Server to be configured - - .PARAMETER SQLInstanceName - Name of the SQL instance to be configued. Default is 'MSSQLSERVER' - - .PARAMETER OptionName - The name of the SQL configuration option to be set - - .PARAMETER OptionValue - The desired value of the SQL configuration option - - .PARAMETER RestartService - Determines whether the instance should be restarted after updating the configuration option - - .PARAMETER RestartTimeout - The length of time, in seconds, to wait for the service to restart. Default is 120 seconds. -#> -function Set-TargetResource -{ - [CmdletBinding()] - param( - [Parameter(Mandatory = $true)] - [String] - $SQLServer, - - [Parameter(Mandatory = $true)] - [String] - $SQLInstanceName, - - [Parameter(Mandatory = $true)] - [String] - $OptionName, - - [Parameter(Mandatory = $true)] - [Int32] - $OptionValue, - - [Boolean] - $RestartService = $false, - - [Int32] - $RestartTimeout = 120 - ) - - $sql = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName - - ## get the configuration option - $option = $sql.Configuration.Properties | Where-Object { $_.DisplayName -eq $OptionName } - - if(!$option) - { - throw New-TerminatingError -ErrorType "ConfigurationOptionNotFound" -FormatArgs $OptionName -ErrorCategory InvalidArgument - } - - $option.ConfigValue = $OptionValue - $sql.Configuration.Alter() - - if ($option.IsDynamic -eq $true) - { - New-VerboseMessage -Message 'Configuration option has been updated.' - } - elseif (($option.IsDynamic -eq $false) -and ($RestartService -eq $true)) - { - New-VerboseMessage -Message 'Configuration option has been updated, restarting instance...' - Restart-SqlService -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName -Timeout $RestartTimeout - } - else - { - New-WarningMessage -WarningType 'ConfigurationRestartRequired' -FormatArgs $OptionName - } -} - -<# - .SYNOPSIS - Determines whether a SQL configuration option value is properly set - - .PARAMETER SQLServer - Hostname of the SQL Server to be configured - - .PARAMETER SQLInstanceName - Name of the SQL instance to be configued. Default is 'MSSQLSERVER' - - .PARAMETER OptionName - The name of the SQL configuration option to be tested - - .PARAMETER OptionValue - The desired value of the SQL configuration option - - .PARAMETER RestartService - *** Not used in this function *** - Determines whether the instance should be restarted after updating the configuration option - - .PARAMETER RestartTimeout - *** Not used in this function *** - The length of time, in seconds, to wait for the service to restart. -#> -function Test-TargetResource -{ - [CmdletBinding()] - [OutputType([Boolean])] - param( - [Parameter(Mandatory = $true)] - [String] - $SQLServer, - - [Parameter(Mandatory = $true)] - [String] - $SQLInstanceName, - - [Parameter(Mandatory = $true)] - [String] - $OptionName, - - [Parameter(Mandatory = $true)] - [Int32] - $OptionValue, - - [Boolean] - $RestartService = $false, - - [Int32] - $RestartTimeout = 120 - ) - - ## Get the current state of the configuration item - $state = Get-TargetResource @PSBoundParameters - - ## return whether the value matches the desired state - return ($state.OptionValue -eq $OptionValue) -} - -Export-ModuleMember -Function *-TargetResource diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerDatabasePermission/MSFT_xSQLServerDatabasePermission.psm1 b/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerDatabasePermission/MSFT_xSQLServerDatabasePermission.psm1 deleted file mode 100644 index f0614f322..000000000 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerDatabasePermission/MSFT_xSQLServerDatabasePermission.psm1 +++ /dev/null @@ -1,278 +0,0 @@ -Import-Module -Name (Join-Path -Path (Split-Path (Split-Path $PSScriptRoot -Parent) -Parent) -ChildPath 'xSQLServerHelper.psm1') -Force - -<# - .SYNOPSIS - Returns the current permissions for the user in the database - - .PARAMETER Ensure - This is The Ensure if the permission should be granted (Present) or revoked (Absent) - Not used in Get-TargetResource - - .PARAMETER Database - This is the SQL database - - .PARAMETER Name - This is the name of the SQL login for the permission set - - .PARAMETER PermissionState - This is the state of permission set. Valid values are 'Grant' or 'Deny' - - .PARAMETER Permissions - This is a list that represents a SQL Server set of database permissions - - .PARAMETER SQLServer - This is the SQL Server for the database - - .PARAMETER SQLInstanceName - This is the SQL instance for the database -#> -function Get-TargetResource -{ - [CmdletBinding()] - [OutputType([System.Collections.Hashtable])] - param - ( - [ValidateSet('Present','Absent')] - [System.String] - $Ensure, - - [parameter(Mandatory = $true)] - [System.String] - $Database, - - [parameter(Mandatory = $true)] - [System.String] - $Name, - - [parameter(Mandatory = $true)] - [ValidateSet('Grant','Deny')] - [System.String] - $PermissionState, - - [parameter(Mandatory = $true)] - [System.String[]] - $Permissions, - - [parameter(Mandatory = $true)] - [System.String] - $SQLServer = $env:COMPUTERNAME, - - [parameter(Mandatory = $true)] - [System.String] - $SQLInstanceName = 'MSSQLSERVER' - ) - - $sqlServerObject = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName - - if ($sqlServerObject) - { - Write-Verbose -Message "Getting permissions for user '$Name' in database '$Database'" - $getSqlDatabasePermissionResult = Get-SqlDatabasePermission -SqlServerObject $sqlServerObject ` - -Name $Name ` - -Database $Database ` - -PermissionState $PermissionState - - if ($getSqlDatabasePermissionResult) - { - $resultOfPermissionCompare = Compare-Object -ReferenceObject $Permissions ` - -DifferenceObject $getSqlDatabasePermissionResult - if ($null -eq $resultOfPermissionCompare) - { - $Ensure = 'Present' - } - else - { - $Ensure = 'Absent' - } - } - else - { - $Ensure = 'Absent' - } - } - else - { - throw New-TerminatingError -ErrorType ConnectSQLError ` - -FormatArgs @($SQLServer,$SQLInstanceName) ` - -ErrorCategory InvalidOperation - } - - $returnValue = @{ - Ensure = $Ensure - Database = $Database - Name = $Name - PermissionState = $PermissionState - Permissions = $getSqlDatabasePermissionResult - SQLServer = $SQLServer - SQLInstanceName = $SQLInstanceName - } - - $returnValue -} - -<# - .SYNOPSIS - Sets the permissions for the user in the database. - - .PARAMETER Ensure - This is The Ensure if the permission should be granted (Present) or revoked (Absent) - - .PARAMETER Database - This is the SQL database - - .PARAMETER Name - This is the name of the SQL login for the permission set - - .PARAMETER PermissionState - This is the state of permission set. Valid values are 'Grant' or 'Deny' - - .PARAMETER Permissions - This is a list that represents a SQL Server set of database permissions - - .PARAMETER SQLServer - This is the SQL Server for the database - - .PARAMETER SQLInstanceName - This is the SQL instance for the database -#> -function Set-TargetResource -{ - [CmdletBinding()] - param - ( - [ValidateSet('Present','Absent')] - [System.String] - $Ensure = 'Present', - - [parameter(Mandatory = $true)] - [System.String] - $Database, - - [parameter(Mandatory = $true)] - [System.String] - $Name, - - [parameter(Mandatory = $true)] - [ValidateSet('Grant','Deny')] - [System.String] - $PermissionState, - - [parameter(Mandatory = $true)] - [System.String[]] - $Permissions, - - [parameter(Mandatory = $true)] - [System.String] - $SQLServer = $env:COMPUTERNAME, - - [parameter(Mandatory = $true)] - [System.String] - $SQLInstanceName = 'MSSQLSERVER' - ) - - $sqlServerObject = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName - - if ($sqlServerObject) - { - Write-Verbose -Message "Setting permissions of database '$Database' for login '$Name'" - - if ($Ensure -eq 'Present') - { - Add-SqlDatabasePermission -SqlServerObject $sqlServerObject ` - -Name $Name ` - -Database $Database ` - -PermissionState $PermissionState ` - -Permissions $Permissions - - New-VerboseMessage -Message "$PermissionState - SQL Permissions for $Name, successfullly added in $Database" - } - else - { - Remove-SqlDatabasePermission -SqlServerObject $sqlServerObject ` - -Name $Name ` - -Database $Database ` - -PermissionState $PermissionState ` - -Permissions $Permissions - - New-VerboseMessage -Message "$PermissionState - SQL Permissions for $Name, successfullly removed in $Database" - } - } - else - { - throw New-TerminatingError -ErrorType ConnectSQLError ` - -FormatArgs @($SQLServer,$SQLInstanceName) ` - -ErrorCategory InvalidOperation - } -} - -<# - .SYNOPSIS - Tests if the permissions is set for the user in the database - - .PARAMETER Ensure - This is The Ensure if the permission should be granted (Present) or revoked (Absent) - - .PARAMETER Database - This is the SQL database - - .PARAMETER Name - This is the name of the SQL login for the permission set - - .PARAMETER PermissionState - This is the state of permission set. Valid values are 'Grant' or 'Deny' - - .PARAMETER Permissions - This is a list that represents a SQL Server set of database permissions - - .PARAMETER SQLServer - This is the SQL Server for the database - - .PARAMETER SQLInstanceName - This is the SQL instance for the database -#> -function Test-TargetResource -{ - [CmdletBinding()] - [OutputType([System.Boolean])] - param - ( - [ValidateSet('Present','Absent')] - [System.String] - $Ensure = 'Present', - - [parameter(Mandatory = $true)] - [System.String] - $Database, - - [parameter(Mandatory = $true)] - [System.String] - $Name, - - [parameter(Mandatory = $true)] - [ValidateSet('Grant','Deny')] - [System.String] - $PermissionState, - - [parameter(Mandatory = $true)] - [System.String[]] - $Permissions, - - [parameter(Mandatory = $true)] - [System.String] - $SQLServer = $env:COMPUTERNAME, - - [parameter(Mandatory = $true)] - [System.String] - $SQLInstanceName = 'MSSQLSERVER' - ) - - Write-Verbose -Message "Evaluating permissions for user '$Name' in database '$Database'." - - $getTargetResourceResult = Get-TargetResource @PSBoundParameters - - return Test-SQLDscParameterState -CurrentValues $getTargetResourceResult ` - -DesiredValues $PSBoundParameters ` - -ValuesToCheck @('Name', 'Ensure', 'PermissionState', 'Permissions') -} - -Export-ModuleMember -Function *-TargetResource diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerFailoverClusterSetup/MSFT_xSQLServerFailoverClusterSetup.psm1 b/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerFailoverClusterSetup/MSFT_xSQLServerFailoverClusterSetup.psm1 deleted file mode 100644 index 832a1facc..000000000 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerFailoverClusterSetup/MSFT_xSQLServerFailoverClusterSetup.psm1 +++ /dev/null @@ -1,1038 +0,0 @@ -# NOTE: This resource requires WMF5 and PsDscRunAsCredential - -$currentPath = Split-Path -Parent $MyInvocation.MyCommand.Path -Write-Debug -Message "CurrentPath: $currentPath" - -# Load Common Code -Import-Module $currentPath\..\..\xSQLServerHelper.psm1 -Verbose:$false -ErrorAction Stop - -function Get-TargetResource -{ - [CmdletBinding()] - [OutputType([System.Collections.Hashtable])] - param - ( - [parameter(Mandatory = $true)] - [ValidateSet("Prepare","Complete")] - [System.String] - $Action, - - [System.String] - $SourcePath = "$PSScriptRoot\..\..\", - - [System.String] - $SourceFolder = "Source", - - [parameter(Mandatory = $true)] - [System.Management.Automation.PSCredential] - $SetupCredential, - - [System.Management.Automation.PSCredential] - $SourceCredential, - - [System.Boolean] - $SuppressReboot, - - [System.Boolean] - $ForceReboot, - - [parameter(Mandatory = $true)] - [System.String] - $Features, - - [parameter(Mandatory = $true)] - [System.String] - $InstanceName, - - [System.String] - $InstanceID = $InstanceName, - - [System.String] - $PID, - - [System.String] - $UpdateEnabled = $True, - - [System.String] - $UpdateSource = ".\Updates", - - [System.String] - $SQMReporting, - - [System.String] - $ErrorReporting, - - [System.String] - $FailoverClusterGroup = "SQL Server ($InstanceName)", - - [parameter(Mandatory = $true)] - [System.String] - $FailoverClusterNetworkName, - - [System.String] - $FailoverClusterIPAddress, - - [System.String] - $InstallSharedDir, - - [System.String] - $InstallSharedWOWDir, - - [System.String] - $InstanceDir, - - [parameter(Mandatory = $true)] - [System.Management.Automation.PSCredential] - $SQLSvcAccount, - - [System.Management.Automation.PSCredential] - $AgtSvcAccount = $SQLSvcAccount, - - [System.String] - $SQLCollation, - - [System.String[]] - $SQLSysAdminAccounts, - - [System.String] - $SecurityMode, - - [System.Management.Automation.PSCredential] - $SAPwd = $SetupCredential, - - [System.String] - $InstallSQLDataDir, - - [System.String] - $SQLUserDBDir, - - [System.String] - $SQLUserDBLogDir, - - [System.String] - $SQLTempDBDir, - - [System.String] - $SQLTempDBLogDir, - - [System.String] - $SQLBackupDir, - - [System.Management.Automation.PSCredential] - $ASSvcAccount = $SQLSvcAccount, - - [System.String] - $ASCollation, - - [System.String[]] - $ASSysAdminAccounts, - - [System.String] - $ASDataDir, - - [System.String] - $ASLogDir, - - [System.String] - $ASBackupDir, - - [System.String] - $ASTempDir, - - [System.String] - $ASConfigDir, - - [System.Management.Automation.PSCredential] - $ISSvcAccount = $SQLSvcAccount, - - [System.String] - $ISFileSystemFolder - ) - - $InstanceName = $InstanceName.ToUpper() - - Import-Module $PSScriptRoot\..\..\xPDT.psm1 - - if($SourceCredential) - { - NetUse -SourcePath $SourcePath -Credential $SourceCredential -Ensure "Present" - } - $Path = Join-Path -Path (Join-Path -Path $SourcePath -ChildPath $SourceFolder) -ChildPath "setup.exe" - $Path = ResolvePath $Path - Write-Verbose "Path: $Path" - $SQLVersion = GetSQLVersion -Path $Path - if($SourceCredential) - { - NetUse -SourcePath $SourcePath -Credential $SourceCredential -Ensure "Absent" - } - - if($InstanceName -eq "MSSQLSERVER") - { - $DBServiceName = "MSSQLSERVER" - $AgtServiceName = "SQLSERVERAGENT" - $ASServiceName = "MSSQLServerOLAPService" - } - else - { - $DBServiceName = "MSSQL`$$InstanceName" - $AgtServiceName = "SQLAgent`$$InstanceName" - $ASServiceName = "MSOLAP`$$InstanceName" - } - $ISServiceName = "MsDtsServer" + $SQLVersion + "0" - - if(Get-WmiObject -Namespace root/mscluster -Class MSCluster_ResourceGroup -ErrorAction SilentlyContinue | Where-Object {$_.Name -eq $FailoverClusterGroup}) - { - $Complete = $true - $FailoverClusterNetworkName = (Get-ClusterGroup -Name $FailoverClusterGroup | Get-ClusterResource | Where-Object {$_.ResourceType -eq "Network Name"} | Get-ClusterParameter -Name "Name").Value - $FailoverClusterIPAddress = (Get-ClusterGroup -Name $FailoverClusterGroup | Get-ClusterResource | Where-Object {$_.ResourceType -eq "IP Address"} | Get-ClusterParameter -Name "Address").Value - } - else - { - $FailoverClusterGroup = $null - $FailoverClusterNetworkName = $null - $FailoverClusterIPAddress = $null - $Complete = $false - } - - $Services = Get-Service - $Features = "" - if($Services | Where-Object {$_.Name -eq $DBServiceName}) - { - $Features += "SQLENGINE," - $SQLSvcAccountUsername = (Get-WmiObject -Class Win32_Service | Where-Object {$_.Name -eq $DBServiceName}).StartName - $AgtSvcAccountUsername = (Get-WmiObject -Class Win32_Service | Where-Object {$_.Name -eq $AgtServiceName}).StartName - $InstanceID = ((Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL' -Name $InstanceName).$InstanceName).Split(".")[1] - $FullInstanceID = (Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL' -Name $InstanceName).$InstanceName - $InstanceID = $FullInstanceID.Split(".")[1] - $InstanceDir = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$FullInstanceID\Setup" -Name 'SqlProgramDir').SqlProgramDir.Trim("\") - } - if($Services | Where-Object {$_.Name -eq $ASServiceName}) - { - $Features += "AS," - $ASSvcAccountUsername = (Get-WmiObject -Class Win32_Service | Where-Object {$_.Name -eq $ASServiceName}).StartName - } - if($Services | Where-Object {$_.Name -eq $ISServiceName}) - { - $Features += "IS," - $ISSvcAccountUsername = (Get-WmiObject -Class Win32_Service | Where-Object {$_.Name -eq $ISServiceName}).StartName - } - $Products = Get-WmiObject -Class Win32_Product - switch($SQLVersion) - { - "11" - { - $IdentifyingNumber = "{A7037EB2-F953-4B12-B843-195F4D988DA1}" - } - "12" - { - $IdentifyingNumber = "{75A54138-3B98-4705-92E4-F619825B121F}" - } - } - if($Products | Where-Object {$_.IdentifyingNumber -eq $IdentifyingNumber}) - { - $Features += "SSMS," - } - switch($SQLVersion) - { - "11" - { - $IdentifyingNumber = "{7842C220-6E9A-4D5A-AE70-0E138271F883}" - } - "12" - { - $IdentifyingNumber = "{B5ECFA5C-AC4F-45A4-A12E-A76ABDD9CCBA}" - } - } - if($Products | Where-Object {$_.IdentifyingNumber -eq $IdentifyingNumber}) - { - $Features += "ADV_SSMS," - } - $Features = $Features.Trim(",") - if($Features -ne "") - { - switch($SQLVersion) - { - "11" - { - $InstallSharedDir = (GetFirstItemPropertyValue -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components" -Name "FEE2E540D20152D4597229B6CFBC0A69") - $InstallSharedWOWDir = (GetFirstItemPropertyValue -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components" -Name "A79497A344129F64CA7D69C56F5DD8B4") - } - "12" - { - $InstallSharedDir = (GetFirstItemPropertyValue -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components" -Name "FEE2E540D20152D4597229B6CFBC0A69") - $InstallSharedWOWDir = (GetFirstItemPropertyValue -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components" -Name "C90BFAC020D87EA46811C836AD3C507F") - } - "13" - { - $InstallSharedDir = (GetFirstItemPropertyValue -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components" -Name "FEE2E540D20152D4597229B6CFBC0A69") - $InstallSharedWOWDir = (GetFirstItemPropertyValue -Path "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components" -Name "A79497A344129F64CA7D69C56F5DD8B4") - } - } - } - - $returnValue = @{ - Action = $Action - SourcePath = $SourcePath - SourceFolder = $SourceFolder - Features = $Features - InstanceName = $InstanceName - InstanceID = $InstanceID - FailoverClusterGroup = $FailoverClusterGroup - FailoverClusterNetworkName = $FailoverClusterNetworkName - FailoverClusterIPAddress = $FailoverClusterIPAddress - InstallSharedDir = $InstallSharedDir - InstallSharedWOWDir = $InstallSharedWOWDir - InstanceDir = $InstanceDir - SQLSvcAccountUsername = $SQLSvcAccountUsername - AgtSvcAccountUsername = $AgtSvcAccountUsername - ASSvcAccountUsername = $ASSvcAccountUsername - ISSvcAccountUsername = $ISSvcAccountUsername - } - - $returnValue -} - - -function Set-TargetResource -{ - [CmdletBinding()] - param - ( - [parameter(Mandatory = $true)] - [ValidateSet("Prepare","Complete")] - [System.String] - $Action, - - [System.String] - $SourcePath = "$PSScriptRoot\..\..\", - - [System.String] - $SourceFolder = "Source", - - [parameter(Mandatory = $true)] - [System.Management.Automation.PSCredential] - $SetupCredential, - - [System.Management.Automation.PSCredential] - $SourceCredential, - - [System.Boolean] - $SuppressReboot, - - [System.Boolean] - $ForceReboot, - - [parameter(Mandatory = $true)] - [System.String] - $Features, - - [parameter(Mandatory = $true)] - [System.String] - $InstanceName, - - [System.String] - $InstanceID = $InstanceName, - - [System.String] - $PID, - - [System.String] - $UpdateEnabled = $True, - - [System.String] - $UpdateSource = ".\Updates", - - [System.String] - $SQMReporting, - - [System.String] - $ErrorReporting, - - [System.String] - $FailoverClusterGroup = "SQL Server ($InstanceName)", - - [parameter(Mandatory = $true)] - [System.String] - $FailoverClusterNetworkName, - - [System.String] - $FailoverClusterIPAddress, - - [System.String] - $InstallSharedDir, - - [System.String] - $InstallSharedWOWDir, - - [System.String] - $InstanceDir, - - [parameter(Mandatory = $true)] - [System.Management.Automation.PSCredential] - $SQLSvcAccount, - - [System.Management.Automation.PSCredential] - $AgtSvcAccount = $SQLSvcAccount, - - [System.String] - $SQLCollation, - - [System.String[]] - $SQLSysAdminAccounts, - - [System.String] - $SecurityMode, - - [System.Management.Automation.PSCredential] - $SAPwd = $SetupCredential, - - [System.String] - $InstallSQLDataDir, - - [System.String] - $SQLUserDBDir, - - [System.String] - $SQLUserDBLogDir, - - [System.String] - $SQLTempDBDir, - - [System.String] - $SQLTempDBLogDir, - - [System.String] - $SQLBackupDir, - - [System.Management.Automation.PSCredential] - $ASSvcAccount = $SQLSvcAccount, - - [System.String] - $ASCollation, - - [System.String[]] - $ASSysAdminAccounts, - - [System.String] - $ASDataDir, - - [System.String] - $ASLogDir, - - [System.String] - $ASBackupDir, - - [System.String] - $ASTempDir, - - [System.String] - $ASConfigDir, - - [System.Management.Automation.PSCredential] - $ISSvcAccount = $SQLSvcAccount, - - [System.String] - $ISFileSystemFolder - ) - - $InstanceName = $InstanceName.ToUpper() - - Import-Module $PSScriptRoot\..\..\xPDT.psm1 - - if($SourceCredential) - { - NetUse -SourcePath $SourcePath -Credential $SourceCredential -Ensure "Present" - $TempFolder = [IO.Path]::GetTempPath() - & robocopy.exe (Join-Path -Path $SourcePath -ChildPath $SourceFolder) (Join-Path -Path $TempFolder -ChildPath $SourceFolder) /e - $SourcePath = $TempFolder - NetUse -SourcePath $SourcePath -Credential $SourceCredential -Ensure "Absent" - } - $Path = Join-Path -Path (Join-Path -Path $SourcePath -ChildPath $SourceFolder) -ChildPath "setup.exe" - $Path = ResolvePath $Path - $SQLVersion = GetSQLVersion -Path $Path - - foreach($feature in $Features.Split(",")) - { - if(($SQLVersion -eq "13") -and (($feature -eq "SSMS") -or ($feature -eq "ADV_SSMS"))) - { - Throw New-TerminatingError -ErrorType FeatureNotSupported -FormatArgs @($feature) -ErrorCategory InvalidData - } - } - - switch($Action) - { - "Prepare" - { - # If SQL shared components already installed, clear InstallShared*Dir variables - switch($SQLVersion) - { - "11" - { - if((Get-Variable -Name "InstallSharedDir" -ErrorAction SilentlyContinue) -and (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\30AE1F084B1CF8B4797ECB3CCAA3B3B6" -ErrorAction SilentlyContinue)) - { - Set-Variable -Name "InstallSharedDir" -Value "" - } - if((Get-Variable -Name "InstallSharedWOWDir" -ErrorAction SilentlyContinue) -and (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\A79497A344129F64CA7D69C56F5DD8B4" -ErrorAction SilentlyContinue)) - { - Set-Variable -Name "InstallSharedWOWDir" -Value "" - } - } - "12" - { - if((Get-Variable -Name "InstallSharedDir" -ErrorAction SilentlyContinue) -and (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\FEE2E540D20152D4597229B6CFBC0A69" -ErrorAction SilentlyContinue)) - { - Set-Variable -Name "InstallSharedDir" -Value "" - } - if((Get-Variable -Name "InstallSharedWOWDir" -ErrorAction SilentlyContinue) -and (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\C90BFAC020D87EA46811C836AD3C507F" -ErrorAction SilentlyContinue)) - { - Set-Variable -Name "InstallSharedWOWDir" -Value "" - } - } - "13" - { - if((Get-Variable -Name "InstallSharedDir" -ErrorAction SilentlyContinue) -and (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\FEE2E540D20152D4597229B6CFBC0A69" -ErrorAction SilentlyContinue)) - { - Set-Variable -Name "InstallSharedDir" -Value "" - } - if((Get-Variable -Name "InstallSharedWOWDir" -ErrorAction SilentlyContinue) -and (Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\A79497A344129F64CA7D69C56F5DD8B4" -ErrorAction SilentlyContinue)) - { - Set-Variable -Name "InstallSharedWOWDir" -Value "" - } - } - } - - # Create install arguments - $Arguments = "/SkipRules=`"Cluster_VerifyForErrors`" /Quiet=`"True`" /IAcceptSQLServerLicenseTerms=`"True`" /Action=`"PrepareFailoverCluster`"" - $ArgumentVars = @( - "InstanceName", - "InstanceID", - "UpdateEnabled", - "UpdateSource", - "Features", - "PID", - "SQMReporting", - "ErrorReporting", - "InstallSharedDir", - "InstallSharedWOWDir", - "InstanceDir" - ) - foreach($ArgumentVar in $ArgumentVars) - { - if((Get-Variable -Name $ArgumentVar).Value -ne "") - { - $Arguments += " /$ArgumentVar=`"" + (Get-Variable -Name $ArgumentVar).Value + "`"" - } - } - if($Features.Contains("SQLENGINE")) - { - $Arguments += " /AgtSvcAccount=`"" + $AgtSvcAccount.UserName + "`"" - $Arguments += " /AgtSvcPassword=`"" + $AgtSvcAccount.GetNetworkCredential().Password + "`"" - $Arguments += " /SQLSvcAccount=`"" + $SQLSvcAccount.UserName + "`"" - $Arguments += " /SQLSvcPassword=`"" + $SQLSvcAccount.GetNetworkCredential().Password + "`"" - } - if($Features.Contains("AS")) - { - $Arguments += " /ASSvcAccount=`"" + $ASSvcAccount.UserName + "`"" - $Arguments += " /ASSvcPassword=`"" + $ASSvcAccount.GetNetworkCredential().Password + "`"" - } - if($Features.Contains("IS")) - { - $Arguments += " /ISSvcAccount=`"" + $ISSvcAccount.UserName + "`"" - $Arguments += " /ISSvcPassword=`"" + $ISSvcAccount.GetNetworkCredential().Password + "`"" - } - } - "Complete" - { - # Remove trailing "\" from paths - foreach($Var in @("InstallSQLDataDir","SQLUserDBDir","SQLUserDBLogDir","SQLTempDBDir","SQLTempDBLogDir","SQLBackupDir","ASDataDir","ASLogDir","ASBackupDir","ASTempDir","ASConfigDir","ISFileSystemFolder")) - { - if(Get-Variable -Name $Var -ErrorAction SilentlyContinue) - { - Set-Variable -Name $Var -Value (Get-Variable -Name $Var).Value.TrimEnd("\") - } - } - - # Discover which cluster disks need to be added to this cluster group - $Drives = @() - foreach($Var in @("InstallSQLDataDir","SQLUserDBDir","SQLUserDBLogDir","SQLTempDBDir","SQLTempDBLogDir","SQLBackupDir","ASDataDir","ASLogDir","ASBackupDir","ASTempDir","ASConfigDir","ISFileSystemFolder")) - { - if( - (Get-Variable -Name $Var -ErrorAction SilentlyContinue) -and ` - ((Get-Variable -Name $Var).Value.Length -ge 2) -and ` - ((Get-Variable -Name $Var).Value.Substring(1,1) -eq ":") - ) - { - $Drives += (Get-Variable -Name $Var).Value.Substring(0,2) - } - } - $Drives = $Drives | Sort-Object -Unique - $FailoverClusterDisks = @() - $DiskResources = Get-WmiObject -Class MSCluster_Resource -Namespace root/mscluster | Where-Object {$_.Type -eq "Physical Disk"} - foreach($DiskResource in $DiskResources) - { - $Disks = Get-WmiObject -Namespace root/mscluster -Query "Associators of {$DiskResource} Where ResultClass=MSCluster_Disk" - foreach($Disk in $Disks) - { - $Partitions = Get-WmiObject -Namespace root/mscluster -Query "Associators of {$Disk} Where ResultClass=MSCluster_DiskPartition" - foreach($Partition in $Partitions) - { - foreach($Drive in $Drives) - { - if($Partition.Path -eq $Drive) - { - $FailoverClusterDisks += $DiskResource.Name - } - } - } - } - } - - # Discover which cluster network to use for this cluster group - $ClusterNetworks = @(Get-WmiObject -Namespace root/mscluster -Class MSCluster_Network) - if([String]::IsNullOrEmpty($FailoverClusterIPAddress)) - { - $FailoverClusterIPAddresses = "IPv4;DHCP;" + $ClusterNetwork[0].Name - } - else - { - $FailoverClusterIPAddressDecimal = ConvertDecimalIP -IPAddress $FailoverClusterIPAddress - foreach($ClusterNetwork in $ClusterNetworks) - { - $ClusterNetworkAddressDecimal = ConvertDecimalIP -IPAddress $ClusterNetwork.Address - $ClusterNetworkAddressMaskDecimal = ConvertDecimalIP -IPAddress $ClusterNetwork.AddressMask - if(($FailoverClusterIPAddressDecimal -band $ClusterNetworkAddressMaskDecimal) -eq ($ClusterNetworkAddressDecimal -band $ClusterNetworkAddressMaskDecimal)) - { - $FailoverClusterIPAddresses = "IPv4;$FailoverClusterIPAddress;" + $ClusterNetwork.Name + ";" + $ClusterNetwork.AddressMask - } - } - } - - # Create install arguments - $Arguments = "/SkipRules=`"Cluster_VerifyForErrors`" /Quiet=`"True`" /IAcceptSQLServerLicenseTerms=`"True`" /Action=`"CompleteFailoverCluster`"" - $ArgumentVars = @( - "InstanceName", - "FailoverClusterGroup", - "FailoverClusterNetworkName", - "FailoverClusterIPAddresses" - ) - if($Features.Contains("SQLENGINE")) - { - $ArgumentVars += @( - "SecurityMode", - "SQLCollation", - "InstallSQLDataDir", - "SQLUserDBDir", - "SQLUserDBLogDir", - "SQLTempDBDir", - "SQLTempDBLogDir", - "SQLBackupDir" - ) - } - if($Features.Contains("AS")) - { - $ArgumentVars += @( - "ASCollation", - "ASDataDir", - "ASLogDir", - "ASBackupDir", - "ASTempDir", - "ASConfigDir" - ) - } - foreach($ArgumentVar in $ArgumentVars) - { - if((Get-Variable -Name $ArgumentVar).Value -ne "") - { - $Arguments += " /$ArgumentVar=`"" + (Get-Variable -Name $ArgumentVar).Value + "`"" - } - } - if($FailoverClusterDisks.Count -ne 0) - { - $Arguments += " /FailoverClusterDisks=" - foreach($FailoverClusterDisk in $FailoverClusterDisks) - { - $Arguments +="`"$FailoverClusterDisk`" " - } - $Arguments = $Arguments.Trim() - } - if($Features.Contains("SQLENGINE")) - { - $Arguments += " /SQLSysAdminAccounts=`"" + $SetupCredential.UserName + "`"" - if($PSBoundParameters.ContainsKey("SQLSysAdminAccounts")) - { - foreach($AdminAccount in $SQLSysAdminAccounts) - { - $Arguments += " `"$AdminAccount`"" - } - } - if($SecurityMode -eq "SQL") - { - $Arguments += " /SAPwd=`"" + $SAPwd.GetNetworkCredential().Password + "`"" - } - } - if($Features.Contains("AS")) - { - $Arguments += " /ASSysAdminAccounts=`"" + $SetupCredential.UserName + "`"" - if($PSBoundParameters.ContainsKey("ASSysAdminAccounts")) - { - foreach($AdminAccount in $ASSysAdminAccounts) - { - $Arguments += " `"$AdminAccount`"" - } - } - } - } - } - - # Replace sensitive values for verbose output - $Log = $Arguments - if($PID -ne "") - { - $Log = $Log.Replace($PID,"*****-*****-*****-*****-*****") - } - if($SecurityMode -eq "SQL") - { - $Log = $Log.Replace($SAPwd.GetNetworkCredential().Password,"********") - } - $LogVars = @("AgtSvcAccount","SQLSvcAccount","ASSvcAccount","ISSvcAccount") - foreach($LogVar in $LogVars) - { - if((Get-Variable -Name $LogVar).Value -ne "") - { - $Log = $Log.Replace((Get-Variable -Name $LogVar).Value.GetNetworkCredential().Password,"********") - } - } - - Write-Verbose "Path: $Path" - Write-Verbose "Arguments: $Log" - - switch($Action) - { - 'Prepare' - { - $Process = StartWin32Process -Path $Path -Arguments $Arguments -Credential $SetupCredential -AsTask - } - 'Complete' - { - $Process = StartWin32Process -Path $Path -Arguments $Arguments - } - } - Write-Verbose $Process - WaitForWin32ProcessEnd -Path $Path -Arguments $Arguments -Credential $SetupCredential - - # Additional "Prepare" actions - if($Action -eq "Prepare") - { - # Configure integration services - if($Features.Contains("IS")) - { - $MsDtsSrvrPath = (Get-ItemProperty -Path ("HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\" + $SQLVersion + "0\SSIS\ServiceConfigFile") -Name '(default)').'(default)' - if(Test-Path $MsDtsSrvrPath) - { - $MsDtsSrvr = [XML](Get-Content $MsDtsSrvrPath) - if($FailoverClusterNetworkName -eq "") - { - $FailoverClusterNetworkName = "." - } - if($InstanceName -eq "MSSQLSERVER") - { - $MsDtsSrvr.DtsServiceConfiguration.TopLevelFolders.Folder | Where-Object {$_.type -eq "SqlServerFolder"} | ForEach-Object {$_.ServerName = "$FailoverClusterNetworkName"} - } - else - { - $MsDtsSrvr.DtsServiceConfiguration.TopLevelFolders.Folder | Where-Object {$_.type -eq "SqlServerFolder"} | ForEach-Object {$_.ServerName = "$FailoverClusterNetworkName\$InstanceName"} - } - $MsDtsSrvr.Save($MsDtsSrvrPath) - Restart-Service -Name ("MsDtsServer" + $SQLVersion + "0") - } - } - } - - # Additional "Complete" actions - if($Action -eq "Complete") - { - # Workaround for Analysis Services IPv6 issue, see KB2658571 - if($Features.Contains("AS")) - { - $msmredirpath = [Environment]::ExpandEnvironmentVariables("%ProgramFiles(x86)%\Microsoft SQL Server\90\Shared\ASConfig\msmdredir.ini") - if(Test-Path ($msmredirpath)) - { - $msmdredir = [XML](Get-Content $msmredirpath) - if($msmdredir.ConfigurationSettings.Instances.Instance | Where-Object {$_.Name -eq $InstanceName} | ForEach-Object {$_.PortIPv6}) - { - $Entry = $msmdredir.ConfigurationSettings.Instances.Instance | Where-Object {$_.Name -eq $InstanceName} | ForEach-Object {$_.SelectSingleNode('PortIPv6')} - $msmdredir.ConfigurationSettings.Instances.Instance | Where-Object {$_.Name -eq $InstanceName} | ForEach-Object {$_.RemoveChild($Entry)} - $msmdredir.Save($msmredirpath) - Stop-ClusterGroup -Name $FailoverClusterGroup - Start-ClusterGroup -Name $FailoverClusterGroup - } - } - } - - # Create path for Integration Services - if($Features.Contains("IS") -and ($ISFileSystemFolder -ne "")) - { - if(($ISFileSystemFolder.Length -ge 2) -and ($ISFileSystemFolder.Substring(1,1) -eq ":")) - { - Invoke-Command -ScriptBlock { - $ISFileSystemFolder = $args[0] - if((Test-Path -Path $ISFileSystemFolder.Substring(0,2)) -and !(Test-Path -Path $ISFileSystemFolder)) - { - New-Item -Path $ISFileSystemFolder -ItemType Directory - } - } -ComputerName . -ArgumentList @($ISFileSystemFolder) - } - } - } - - if($ForceReboot -or ((Get-ItemProperty -Path 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager' -Name 'PendingFileRenameOperations' -ErrorAction SilentlyContinue) -ne $null)) - { - if(!($SuppressReboot)) - { - $global:DSCMachineStatus = 1 - } - else - { - Write-Verbose "Suppressing reboot" - } - } - - if(!(Test-TargetResource @PSBoundParameters)) - { - throw New-TerminatingError -ErrorType TestFailedAfterSet -ErrorCategory InvalidResult - } -} - - -function Test-TargetResource -{ - [CmdletBinding()] - [OutputType([System.Boolean])] - param - ( - [parameter(Mandatory = $true)] - [ValidateSet("Prepare","Complete")] - [System.String] - $Action, - - [System.String] - $SourcePath = "$PSScriptRoot\..\..\", - - [System.String] - $SourceFolder = "Source", - - [parameter(Mandatory = $true)] - [System.Management.Automation.PSCredential] - $SetupCredential, - - [System.Management.Automation.PSCredential] - $SourceCredential, - - [System.Boolean] - $SuppressReboot, - - [System.Boolean] - $ForceReboot, - - [parameter(Mandatory = $true)] - [System.String] - $Features, - - [parameter(Mandatory = $true)] - [System.String] - $InstanceName, - - [System.String] - $InstanceID = $InstanceName, - - [System.String] - $PID, - - [System.String] - $UpdateEnabled = $True, - - [System.String] - $UpdateSource = ".\Updates", - - [System.String] - $SQMReporting, - - [System.String] - $ErrorReporting, - - [System.String] - $FailoverClusterGroup = "SQL Server ($InstanceName)", - - [parameter(Mandatory = $true)] - [System.String] - $FailoverClusterNetworkName, - - [System.String] - $FailoverClusterIPAddress, - - [System.String] - $InstallSharedDir, - - [System.String] - $InstallSharedWOWDir, - - [System.String] - $InstanceDir, - - [parameter(Mandatory = $true)] - [System.Management.Automation.PSCredential] - $SQLSvcAccount, - - [System.Management.Automation.PSCredential] - $AgtSvcAccount = $SQLSvcAccount, - - [System.String] - $SQLCollation, - - [System.String[]] - $SQLSysAdminAccounts, - - [System.String] - $SecurityMode, - - [System.Management.Automation.PSCredential] - $SAPwd = $SetupCredential, - - [System.String] - $InstallSQLDataDir, - - [System.String] - $SQLUserDBDir, - - [System.String] - $SQLUserDBLogDir, - - [System.String] - $SQLTempDBDir, - - [System.String] - $SQLTempDBLogDir, - - [System.String] - $SQLBackupDir, - - [System.Management.Automation.PSCredential] - $ASSvcAccount = $SQLSvcAccount, - - [System.String] - $ASCollation, - - [System.String[]] - $ASSysAdminAccounts, - - [System.String] - $ASDataDir, - - [System.String] - $ASLogDir, - - [System.String] - $ASBackupDir, - - [System.String] - $ASTempDir, - - [System.String] - $ASConfigDir, - - [System.Management.Automation.PSCredential] - $ISSvcAccount = $SQLSvcAccount, - - [System.String] - $ISFileSystemFolder - ) - - switch($Action) - { - "Prepare" - { - $SQLData = Get-TargetResource @PSBoundParameters - - $result = $true - foreach($Feature in $Features.Split(",")) - { - if(!($SQLData.Features.Contains($Feature))) - { - $result = $false - } - } - } - "Complete" - { - if(Get-WmiObject -Namespace root/mscluster -Class MSCluster_ResourceGroup -ErrorAction SilentlyContinue | Where-Object {$_.Name -eq $FailoverClusterGroup}) - { - $result = $true - } - else - { - $result = $false - } - } - } - - $result -} - - -function GetSQLVersion -{ - [CmdletBinding()] - param - ( - [Parameter(Mandatory=$true)] - [String] - $Path - ) - - (Get-Item -Path $Path).VersionInfo.ProductVersion.Split(".")[0] -} - - -function GetFirstItemPropertyValue -{ - [CmdletBinding()] - param - ( - [Parameter(Mandatory=$true)] - [String] - $Path, - - [Parameter(Mandatory=$true)] - [String] - $Name - ) - - if(Get-ItemProperty -Path "$Path\$Name" -ErrorAction SilentlyContinue) - { - $FirstName = ((Get-ItemProperty -Path "$Path\$Name") | Get-Member -MemberType NoteProperty | Where-Object {$_.Name.Substring(0,2) -ne "PS"}).Name[0] - (Get-ItemProperty -Path "$Path\$Name" -Name $FirstName).$FirstName.TrimEnd("\") - } -} - - -function ConvertDecimalIP -{ - [CmdLetBinding()] - param( - [Parameter(Mandatory = $true)] - [Net.IPAddress] - $IPAddress - ) - - $i = 3 - $DecimalIP = 0 - $IPAddress.GetAddressBytes() | ForEach-Object { - $DecimalIP += $_ * [Math]::Pow(256,$i) - $i-- - } - - return [UInt32]$DecimalIP -} - - -Export-ModuleMember -Function *-TargetResource diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerFailoverClusterSetup/MSFT_xSQLServerFailoverClusterSetup.schema.mof b/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerFailoverClusterSetup/MSFT_xSQLServerFailoverClusterSetup.schema.mof deleted file mode 100644 index 1de6c3315..000000000 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerFailoverClusterSetup/MSFT_xSQLServerFailoverClusterSetup.schema.mof +++ /dev/null @@ -1,51 +0,0 @@ -[ClassVersion("1.0.0.0"), FriendlyName("xSQLServerFailoverClusterSetup")] -class MSFT_xSQLServerFailoverClusterSetup : OMI_BaseResource -{ - [Key, Description("Prepare or Complete."), ValueMap{"Prepare","Complete"}, Values{"Prepare","Complete"}] String Action; - [Write, Description("UNC path to the root of the source files for installation.")] String SourcePath; - [Write, Description("Folder within the source path containing the source files for installation.")] String SourceFolder; - [Required, EmbeddedInstance("MSFT_Credential"), Description("Credential to be used to perform the installation.")] String SetupCredential; - [Write, EmbeddedInstance("MSFT_Credential"), Description("Credential to be used to access SourcePath.")] String SourceCredential; - [Write, Description("Suppress reboot.")] Boolean SuppressReboot; - [Write, Description("Force reboot.")] Boolean ForceReboot; - [Required, Description("SQL features to be installed.")] String Features; - [Key, Description("SQL instance to be installed.")] String InstanceName; - [Write, Description("SQL instance ID, if different from InstanceName.")] String InstanceID; - [Write, Description("Product key for licensed installations.")] String PID; - [Write, Description("Enabled updates during installation.")] String UpdateEnabled; - [Write, Description("Source of updates to be applied during installation.")] String UpdateSource; - [Write, Description("Enable customer experience reporting.")] String SQMReporting; - [Write, Description("Enable error reporting.")] String ErrorReporting; - [Write, Description("Name of the resource group to be used for the SQL Server failover cluster.")] String FailoverClusterGroup; - [Required, Description("Network name for the SQL Server failover cluster.")] String FailoverClusterNetworkName; - [Write, Description("IPv4 address for the SQL Server failover cluster.")] String FailoverClusterIPAddress; - [Write, Description("Installation path for shared SQL files.")] String InstallSharedDir; - [Write, Description("Installation path for x86 shared SQL files.")] String InstallSharedWOWDir; - [Write, Description("Installation path for SQL instance files.")] String InstanceDir; - [Required, EmbeddedInstance("MSFT_Credential"), Description("Service account for the SQL service.")] String SQLSvcAccount; - [Read, Description("Output username for the SQL service.")] String SQLSvcAccountUsername; - [Write, EmbeddedInstance("MSFT_Credential"), Description("Service account for the SQL Agent service.")] String AgtSvcAccount; - [Read, Description("Output username for the SQL Agent service.")] String AgtSvcAccountUsername; - [Write, Description("Collation for SQL.")] String SQLCollation; - [Write, Description("Array of accounts to be made SQL administrators.")] String SQLSysAdminAccounts[]; - [Write, Description("Security mode.")] String SecurityMode; - [Write, EmbeddedInstance("MSFT_Credential"), Description("SA password, if SecurityMode=SQL")] String SAPwd; - [Write, Description("Root path for SQL database files.")] String InstallSQLDataDir; - [Write, Description("Path for SQL database files.")] String SQLUserDBDir; - [Write, Description("Path for SQL log files.")] String SQLUserDBLogDir; - [Write, Description("Path for SQL TempDB files.")] String SQLTempDBDir; - [Write, Description("Path for SQL TempDB log files.")] String SQLTempDBLogDir; - [Write, Description("Path for SQL backup files.")] String SQLBackupDir; - [Write, EmbeddedInstance("MSFT_Credential"), Description("Service account for Analysus Services service.")] String ASSvcAccount; - [Read, Description("Output username for the Analysis Services service.")] String ASSvcAccountUsername; - [Write, Description("Collation for Analysis Services.")] String ASCollation; - [Write, Description("Array of accounts to be made Analysis Services admins.")] String ASSysAdminAccounts[]; - [Write, Description("Path for Analysis Services data files.")] String ASDataDir; - [Write, Description("Path for Analysis Services log files.")] String ASLogDir; - [Write, Description("Path for Analysis Services backup files.")] String ASBackupDir; - [Write, Description("Path for Analysis Services temp files.")] String ASTempDir; - [Write, Description("Path for Analysis Services config.")] String ASConfigDir; - [Write, EmbeddedInstance("MSFT_Credential"), Description("Service account for Integration Services service.")] String ISSvcAccount; - [Read, Description("Output username for the Integration Services service.")] String ISSvcAccountUsername; - [Write, Description("File system folder for Integration Services.")] String ISFileSystemFolder; -}; diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerMaxDop/MSFT_xSQLServerMaxDop.schema.mof b/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerMaxDop/MSFT_xSQLServerMaxDop.schema.mof deleted file mode 100644 index 0ca9038ac..000000000 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerMaxDop/MSFT_xSQLServerMaxDop.schema.mof +++ /dev/null @@ -1,9 +0,0 @@ -[ClassVersion("1.0.0.0"), FriendlyName("xSQLServerMaxDop")] -class MSFT_xSQLServerMaxDop : OMI_BaseResource -{ - [Write, Description("An enumerated value that describes if MaxDop is configured (Present) or reset to default value (Absent)"), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; - [Write, Description("Flag to Dynamically allocate Maxdop based on Best Practices")] Boolean DynamicAlloc; - [Write, Description("Numeric value to configure Maxdop to")] Sint32 MaxDop; - [Write, Description("The host name of the SQL Server to be configured. Default value is '$env:COMPUTERNAME'.")] String SQLServer; - [Key, Description("The name of the SQL instance to be configured.")] String SQLInstanceName; -}; diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerNetwork/MSFT_xSQLServerNetwork.psm1 b/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerNetwork/MSFT_xSQLServerNetwork.psm1 deleted file mode 100644 index 5c8fb2e25..000000000 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerNetwork/MSFT_xSQLServerNetwork.psm1 +++ /dev/null @@ -1,287 +0,0 @@ -Function Get-TargetResource -{ - [CmdletBinding()] - [OutputType([System.Collections.Hashtable])] - param( - [parameter(Mandatory = $true)] - [System.String] - $InstanceName, - - # for now support is just for tcp protocol - # possible future feature to support additional protocols - [parameter(Mandatory = $true)] - [ValidateSet("tcp")] - [System.String] - $ProtocolName - ) - - Write-Verbose "xSQLServerNetwork.Get-TargetResourece ..." - Write-Verbose "Parameters: InstanceName = $InstanceName; ProtocolName = $ProtocolName" - - # create isolated appdomain to load version specific libs, this needed if you have multiple versions of SQL server in the same configuration - $dom_get = [System.AppDomain]::CreateDomain("xSQLServerNetwork_Get_$InstanceName") - - Try - { - $version = GetVersion -InstanceName $InstanceName - - if([string]::IsNullOrEmpty($version)) - { - throw "Unable to resolve SQL version for instance" - } - - $smo = $dom_get.Load("Microsoft.SqlServer.Smo, Version=$version.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91") - $sqlWmiManagement = $dom_get.Load("Microsoft.SqlServer.SqlWmiManagement, Version=$version.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91") - - Write-Verbose "Creating [Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer] object" - $wmi = new-object $sqlWmiManagement.GetType("Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer") - - Write-Verbose "Getting [$ProtocolName] network protocol for [$InstanceName] SQL instance" - $tcp = $wmi.ServerInstances[$InstanceName].ServerProtocols[$ProtocolName] - - Write-Verbose "Reading state values:" - $returnValue = @{ - InstanceName = $InstanceName - ProtocolName = $ProtocolName - IsEnabled = $tcp.IsEnabled - TCPDynamicPorts = $tcp.IPAddresses["IPAll"].IPAddressProperties["TcpDynamicPorts"].Value - TCPPort = $tcp.IPAddresses["IPAll"].IPAddressProperties["TcpPort"].Value - } - - $returnValue.Keys | % { Write-Verbose "$_ = $($returnValue[$_])" } - - } - Finally - { - [System.AppDomain]::Unload($dom_get) - } - - return $returnValue -} - -Function Set-TargetResource -{ - [CmdletBinding()] - param( - [parameter(Mandatory = $true)] - [System.String] - $InstanceName, - - [parameter(Mandatory = $true)] - [ValidateSet("tcp")] - [System.String] - $ProtocolName, - - [System.Boolean] - $IsEnabled, - - [ValidateSet("0")] - [System.String] - $TCPDynamicPorts, - - [System.String] - $TCPPort, - - [System.Boolean] - $RestartService = $false - ) - - Write-Verbose "xSQLServerNetwork.Set-TargetResource ..." - Write-Verbose "Parameters: InstanceName = $InstanceName; ProtocolName = $ProtocolName; IsEnabled=$IsEnabled; TCPDynamicPorts = $TCPDynamicPorts; TCPPort = $TCPPort; RestartService=$RestartService;" - - Write-Verbose "Calling xSQLServerNetwork.Get-TargetResource ..." - $currentState = Get-TargetResource -InstanceName $InstanceName -ProtocolName $ProtocolName - - # create isolated appdomain to load version specific libs, this needed if you have multiple versions of SQL server in the same configuration - $dom_set = [System.AppDomain]::CreateDomain("xSQLServerNetwork_Set_$InstanceName") - - Try - { - $version = GetVersion -InstanceName $InstanceName - - if([string]::IsNullOrEmpty($version)) - { - throw "Unable to resolve SQL version for instance" - } - - $smo = $dom_set.Load("Microsoft.SqlServer.Smo, Version=$version.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91") - $sqlWmiManagement = $dom_set.Load("Microsoft.SqlServer.SqlWmiManagement, Version=$version.0.0.0, Culture=neutral, PublicKeyToken=89845dcd8080cc91") - - $desiredState = @{ - InstanceName = $InstanceName - ProtocolName = $ProtocolName - IsEnabled = $IsEnabled - TCPDynamicPorts = $TCPDynamicPorts - TCPPort = $TCPPort - } - - Write-Verbose "Creating [Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer] object" - $wmi = new-object $sqlWmiManagement.GetType("Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer") - - Write-Verbose "Getting [$ProtocolName] network protocol for [$InstanceName] SQL instance" - $tcp = $wmi.ServerInstances[$InstanceName].ServerProtocols[$ProtocolName] - - Write-Verbose "Checking [IsEnabled] property ..." - if($desiredState["IsEnabled"] -ine $currentState["IsEnabled"]) - { - Write-Verbose "Updating [IsEnabled] from $($currentState["IsEnabled"]) to $($desiredState["IsEnabled"])" - $tcp.IsEnabled = $desiredState["IsEnabled"] - } - - Write-Verbose "Checking [TCPDynamicPorts] property ..." - if($desiredState["TCPDynamicPorts"] -ine $currentState["TCPDynamicPorts"]) - { - Write-Verbose "Updating [TCPDynamicPorts] from $($currentState["TCPDynamicPorts"]) to $($desiredState["TCPDynamicPorts"])" - $tcp.IPAddresses["IPAll"].IPAddressProperties["TcpDynamicPorts"].Value = $desiredState["TCPDynamicPorts"] - } - - Write-Verbose "Checking [TCPPort property] ..." - if($desiredState["TCPPort"] -ine $currentState["TCPPort"]) - { - Write-Verbose "Updating [TCPPort] from $($currentState["TCPPort"]) to $($desiredState["TCPPort"])" - $tcp.IPAddresses["IPAll"].IPAddressProperties["TcpPort"].Value = $desiredState["TCPPort"] - } - - Write-Verbose "Saving changes ..." - $tcp.Alter() - - if($RestartService) - { - Write-Verbose "SQL Service will be restarted ..." - if($InstanceName -eq "MSSQLSERVER") - { - $dbServiceName = "MSSQLSERVER" - $agtServiceName = "SQLSERVERAGENT" - } - else - { - $dbServiceName = "MSSQL`$$InstanceName" - $agtServiceName = "SQLAgent`$$InstanceName" - } - - $sqlService = $wmi.Services[$dbServiceName] - $agentService = $wmi.Services[$agtServiceName] - $startAgent = ($agentService.ServiceState -eq "Running") - - if ($sqlService -eq $null) - { - throw "$dbServiceName service was not found, restart service failed" - } - - Write-Verbose "Stopping [$dbServiceName] service ..." - $sqlService.Stop() - - while($sqlService.ServiceState -ne "Stopped") - { - Start-Sleep -Milliseconds 500 - $sqlService.Refresh() - } - Write-Verbose "[$dbServiceName] service stopped" - - Write-Verbose "Starting [$dbServiceName] service ..." - $sqlService.Start() - - while($sqlService.ServiceState -ne "Running") - { - Start-Sleep -Milliseconds 500 - $sqlService.Refresh() - } - Write-Verbose "[$dbServiceName] service started" - - if ($startAgent) - { - Write-Verbose "Staring [$agtServiceName] service ..." - $agentService.Start() - while($agentService.ServiceState -ne "Running") - { - Start-Sleep -Milliseconds 500 - $agentService.Refresh() - } - Write-Verbose "[$agtServiceName] service started" - } - } - } - Finally - { - [System.AppDomain]::Unload($dom_set) - } -} - -Function Test-TargetResource -{ - [CmdletBinding()] - [OutputType([System.Boolean])] - param( - [parameter(Mandatory = $true)] - [System.String] - $InstanceName, - - [parameter(Mandatory = $true)] - [ValidateSet("tcp")] - [System.String] - $ProtocolName, - - [System.Boolean] - $IsEnabled, - - [ValidateSet("0")] - [System.String] - $TCPDynamicPorts, - - [System.String] - $TCPPort, - - [System.Boolean] - $RestartService = $false - ) - - Write-Verbose "xSQLServerNetwork.Test-TargetResource ..." - Write-Verbose "Parameters: InstanceName = $InstanceName; ProtocolName = $ProtocolName; IsEnabled=$IsEnabled; TCPDynamicPorts = $TCPDynamicPorts; TCPPort = $TCPPort; RestartService=$RestartService;" - - $desiredState = @{ - InstanceName = $InstanceName - ProtocolName = $ProtocolName - IsEnabled = $IsEnabled - TCPDynamicPorts = $TCPDynamicPorts - TCPPort = $TCPPort - } - - Write-Verbose "Calling xSQLServerNetwork.Get-TargetResource ..." - $currentState = Get-TargetResource -InstanceName $InstanceName -ProtocolName $ProtocolName - - Write-Verbose "Comparing desiredState with currentSate ..." - foreach($key in $desiredState.Keys) - { - if($currentState.Keys -eq $key) - { - if($desiredState[$key] -ine $currentState[$key] ) - { - Write-Verbose "$key is different: desired = $($desiredState[$key]); current = $($currentState[$key])" - return $false - } - } - else - { - Write-Verbose "$key is missing" - return $false - } - } - - Write-Verbose "States match" - return $true -} - -Function GetVersion -{ - param( - [parameter(Mandatory = $true)] - [System.String] - $InstanceName - ) - - $instanceId = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\SQL").$InstanceName - $sqlVersion = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$instanceId\Setup").Version - $sqlVersion.Split(".")[0] -} - -Export-ModuleMember -Function *-TargetResource diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerNetwork/MSFT_xSQLServerNetwork.schema.mof b/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerNetwork/MSFT_xSQLServerNetwork.schema.mof deleted file mode 100644 index cf1be7c24..000000000 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerNetwork/MSFT_xSQLServerNetwork.schema.mof +++ /dev/null @@ -1,10 +0,0 @@ -[ClassVersion("1.0.0.0"), FriendlyName("xSQLServerNetwork")] -class MSFT_xSQLServerNetwork : OMI_BaseResource -{ - [Key, Description("SQL Server instance name of which network protocol should be configured")] String InstanceName; - [Required, Description("Network protocol name that should be configured"), ValueMap{"tcp"}, Values{"tcp"}] String ProtocolName; - [Write, Description("Is network protocol should be enabled or disabled")] Boolean IsEnabled; - [Write, Description("If dynamic ports are used should be set to 0, otherwise leave empty"), ValueMap{"0"}, Values{"0"}] String TCPDynamicPorts; - [Write, Description("Sets static port for TCP/IP")] String TCPPort; - [Write, Description("Controls if affected SQL Service should be restarted automatically")] Boolean RestartService; -}; diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerPermission/MSFT_xSQLServerPermission.psm1 b/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerPermission/MSFT_xSQLServerPermission.psm1 deleted file mode 100644 index 5a75b2f30..000000000 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerPermission/MSFT_xSQLServerPermission.psm1 +++ /dev/null @@ -1,252 +0,0 @@ -$ErrorActionPreference = "Stop" - -$script:currentPath = Split-Path -Parent $MyInvocation.MyCommand.Path -Import-Module $script:currentPath\..\..\xSQLServerHelper.psm1 -ErrorAction Stop - -function Get-TargetResource -{ - [CmdletBinding()] - [OutputType([System.Collections.Hashtable])] - param - ( - [Parameter(Mandatory = $true)] - [System.String] - $InstanceName = "DEFAULT", - - [Parameter(Mandatory = $true)] - [System.String] - $NodeName, - - [Parameter(Mandatory = $true)] - [System.String] - $Principal, - - [ValidateSet('AlterAnyAvailabilityGroup','ViewServerState','AlterAnyEndPoint')] - [System.String[]] - $Permission - ) - - New-VerboseMessage -Message "Enumerating permissions for $Principal" - - try { - $instance = Get-SQLPSInstance -NodeName $NodeName -InstanceName $InstanceName - - $permissionSet = Get-SQLServerPermissionSet -Permission $Permission - $enumeratedPermission = $instance.EnumServerPermissions( $Principal, $permissionSet ) | Where-Object { $_.PermissionState -eq "Grant" } - if( $null -ne $enumeratedPermission) { - $grantedPermissionSet = Get-SQLServerPermissionSet -PermissionSet $enumeratedPermission.PermissionType - if( -not ( Compare-Object -ReferenceObject $permissionSet -DifferenceObject $grantedPermissionSet -Property $Permission ) ) { - $ensure = "Present" - } else { - $ensure = "Absent" - } - - $grantedPermission = Get-SQLPermission -ServerPermissionSet $grantedPermissionSet - } else { - $ensure = "Absent" - $grantedPermission = "" - } - } catch { - throw New-TerminatingError -ErrorType PermissionGetError -FormatArgs @($Principal) -ErrorCategory InvalidOperation -InnerException $_.Exception - } - - $returnValue = @{ - InstanceName = [System.String] $InstanceName - NodeName = [System.String] $NodeName - Ensure = [System.String] $ensure - Principal = [System.String] $Principal - Permission = [System.String[]] $grantedPermission - } - - return $returnValue -} - -function Set-TargetResource -{ - [CmdletBinding(SupportsShouldProcess)] - param - ( - [Parameter(Mandatory = $true)] - [System.String] - $InstanceName = "DEFAULT", - - [Parameter(Mandatory = $true)] - [System.String] - $NodeName, - - [ValidateSet("Present","Absent")] - [System.String] - $Ensure, - - [Parameter(Mandatory = $true)] - [System.String] - $Principal, - - [ValidateSet('AlterAnyAvailabilityGroup','ViewServerState','AlterAnyEndPoint')] - [System.String[]] - $Permission - ) - - $parameters = @{ - InstanceName = [System.String] $InstanceName - NodeName = [System.String] $NodeName - Principal = [System.String] $Principal - Permission = [System.String[]] $Permission - } - - $permissionState = Get-TargetResource @parameters - if( $null -ne $permissionState ) { - if( $Ensure -ne "" ) { - if( $permissionState.Ensure -ne $Ensure ) { - $instance = Get-SQLPSInstance -NodeName $NodeName -InstanceName $InstanceName - if( $null -ne $instance ) { - $permissionSet = Get-SQLServerPermissionSet -Permission $Permission - - if( $Ensure -eq "Present") { - if( ( $PSCmdlet.ShouldProcess( $Principal, "Grant permission" ) ) ) { - $instance.Grant($permissionSet, $Principal ) - } - } else { - if( ( $PSCmdlet.ShouldProcess( $Principal, "Revoke permission" ) ) ) { - $instance.Revoke($permissionSet, $Principal ) - } - } - } else { - throw New-TerminatingError -ErrorType PrincipalNotFound -FormatArgs @($Principal) -ErrorCategory ObjectNotFound - } - } else { - New-VerboseMessage -Message "State is already $Ensure" - } - } else { - throw New-TerminatingError -ErrorType PermissionMissingEnsure -FormatArgs @($Principal) -ErrorCategory InvalidOperation - } - } else { - throw New-TerminatingError -ErrorType UnexpectedErrorFromGet -ErrorCategory InvalidResult - } -} - -function Test-TargetResource -{ - [CmdletBinding()] - [OutputType([System.Boolean])] - param - ( - [Parameter(Mandatory = $true)] - [System.String] - $InstanceName = "DEFAULT", - - [Parameter(Mandatory = $true)] - [System.String] - $NodeName, - - [ValidateSet("Present","Absent")] - [System.String] - $Ensure, - - [Parameter(Mandatory = $true)] - [System.String] - $Principal, - - [ValidateSet('AlterAnyAvailabilityGroup','ViewServerState','AlterAnyEndPoint')] - [System.String[]] - $Permission - ) - - $parameters = @{ - InstanceName = [System.String] $InstanceName - NodeName = [System.String] $NodeName - Principal = [System.String] $Principal - Permission = [System.String[]] $Permission - } - - New-VerboseMessage -Message "Testing state of permissions for $Principal" - - $permissionState = Get-TargetResource @parameters - if( $null -ne $permissionState ) { - [System.Boolean] $result = $false - if( $permissionState.Ensure -eq $Ensure) { - $result = $true - } - } else { - throw New-TerminatingError -ErrorType UnexpectedErrorFromGet -ErrorCategory InvalidResult - } - - return $result -} - -function Get-SQLPermission -{ - [CmdletBinding()] - [OutputType([String[]])] - param ( - [Parameter(Mandatory,ParameterSetName="ServerPermissionSet",HelpMessage="Takes a PermissionSet which will be enumerated to return a string array.")] - [Microsoft.SqlServer.Management.Smo.ServerPermissionSet] - [ValidateNotNullOrEmpty()] - $ServerPermissionSet - ) - - [String[]] $permission = @() - - if( $ServerPermissionSet ) { - foreach( $Property in $($ServerPermissionSet | Get-Member -Type Property) ) { - if( $ServerPermissionSet.$($Property.Name) ) { - $permission += $Property.Name - } - } - } - - return [String[]] $permission -} - -function Get-SQLServerPermissionSet -{ - [CmdletBinding()] - [OutputType([Object])] - param - ( - [Parameter(Mandatory,ParameterSetName="Permission",HelpMessage="Takes an array of strings which will be concatenated to a single ServerPermissionSet.")] - [System.String[]] - [ValidateNotNullOrEmpty()] - $Permission, - - [Parameter(Mandatory,ParameterSetName="ServerPermissionSet",HelpMessage="Takes an array of ServerPermissionSet which will be concatenated to a single ServerPermissionSet.")] - [Microsoft.SqlServer.Management.Smo.ServerPermissionSet[]] - [ValidateNotNullOrEmpty()] - $PermissionSet - ) - - if( $Permission ) { - [Microsoft.SqlServer.Management.Smo.ServerPermissionSet] $permissionSet = New-Object -TypeName Microsoft.SqlServer.Management.Smo.ServerPermissionSet - - foreach( $currentPermission in $Permission ) { - $permissionSet.$($currentPermission) = $true - } - } else { - $permissionSet = Merge-SQLPermissionSet -Object $PermissionSet - } - - return $permissionSet -} - -function Merge-SQLPermissionSet { - param ( - [Parameter(Mandatory)] - [Microsoft.SqlServer.Management.Smo.ServerPermissionSet[]] - [ValidateNotNullOrEmpty()] - $Object - ) - - $baseObject = New-Object -TypeName ($Object[0].GetType()) - - foreach ( $currentObject in $Object ) { - foreach( $Property in $($currentObject | Get-Member -Type Property) ) { - if( $currentObject.$($Property.Name) ) { - $baseObject.$($Property.Name) = $currentObject.$($Property.Name) - } - } - } - - return $baseObject -} - -Export-ModuleMember -Function *-TargetResource diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerPermission/MSFT_xSQLServerPermission.schema.mof b/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerPermission/MSFT_xSQLServerPermission.schema.mof deleted file mode 100644 index d92f251aa..000000000 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerPermission/MSFT_xSQLServerPermission.schema.mof +++ /dev/null @@ -1,11 +0,0 @@ - -[ClassVersion("1.0.0.0"), FriendlyName("xSQLServerPermission")] -class MSFT_xSQLServerPermission : OMI_BaseResource -{ - [Key, Description("The SQL Server instance name.")] String InstanceName; - [Required, Description("The host name or FQDN.")] String NodeName; - [Write, Description("If the permission should be present or absent."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; - [Required, Description("The login to which permission will be set.")] String Principal; - [Write, Description("The permission to set for the login."), ValueMap{"AlterAnyAvailabilityGroup","ViewServerState","AlterAnyEndPoint"}, Values{"AlterAnyAvailabilityGroup","ViewServerState","AlterAnyEndPoint"}] String Permission[]; -}; - diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerRSConfig/MSFT_xSQLServerRSConfig.psm1 b/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerRSConfig/MSFT_xSQLServerRSConfig.psm1 deleted file mode 100644 index 6265f171c..000000000 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerRSConfig/MSFT_xSQLServerRSConfig.psm1 +++ /dev/null @@ -1,229 +0,0 @@ -$currentPath = Split-Path -Parent $MyInvocation.MyCommand.Path -Write-Debug -Message "CurrentPath: $currentPath" - -# Load Common Code -Import-Module $currentPath\..\..\xSQLServerHelper.psm1 -Verbose:$false -ErrorAction Stop - -function Get-TargetResource -{ - [CmdletBinding()] - [OutputType([System.Collections.Hashtable])] - param - ( - [parameter(Mandatory = $true)] - [System.String] - $InstanceName, - - [parameter(Mandatory = $true)] - [System.String] - $RSSQLServer, - - [parameter(Mandatory = $true)] - [System.String] - $RSSQLInstanceName, - - [parameter(Mandatory = $true)] - [System.Management.Automation.PSCredential] - $SQLAdminCredential - ) - - if(Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\RS" -Name $InstanceName -ErrorAction SilentlyContinue) - { - $InstanceKey = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\RS" -Name $InstanceName).$InstanceName - $SQLVersion = ((Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$InstanceKey\Setup" -Name "Version").Version).Split(".")[0] - $RSConfig = Invoke-Command -ComputerName . -Credential $SQLAdminCredential -ScriptBlock { - $SQLVersion = $args[0] - $InstanceName = $args[1] - $RSConfig = Get-WmiObject -Class MSReportServer_ConfigurationSetting -Namespace "root\Microsoft\SQLServer\ReportServer\RS_$InstanceName\v$SQLVersion\Admin" - $RSConfig - } -ArgumentList @($SQLVersion,$InstanceName) - if($RSConfig.DatabaseServerName.Contains("\")) - { - $RSSQLServer = $RSConfig.DatabaseServerName.Split("\")[0] - $RSSQLInstanceName = $RSConfig.DatabaseServerName.Split("\")[1] - } - else - { - $RSSQLServer = $RSConfig.DatabaseServerName - $RSSQLInstanceName = "MSSQLSERVER" - } - $IsInitialized = $RSConfig.IsInitialized - } - else - { - throw New-TerminatingError -ErrorType SSRSNotFound -FormatArgs @($InstanceName) -ErrorCategory ObjectNotFound - } - - $returnValue = @{ - InstanceName = $InstanceName - RSSQLServer = $RSSQLServer - RSSQLInstanceName = $RSSQLInstanceName - IsInitialized = $IsInitialized - } - - $returnValue -} - - -function Set-TargetResource -{ - [CmdletBinding()] - param - ( - [parameter(Mandatory = $true)] - [System.String] - $InstanceName, - - [parameter(Mandatory = $true)] - [System.String] - $RSSQLServer, - - [parameter(Mandatory = $true)] - [System.String] - $RSSQLInstanceName, - - [parameter(Mandatory = $true)] - [System.Management.Automation.PSCredential] - $SQLAdminCredential - ) - - if(Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\RS" -Name $InstanceName -ErrorAction SilentlyContinue) - { - Invoke-Command -ComputerName . -Credential $SQLAdminCredential -Authentication Credssp -ScriptBlock { - $InstanceName = $args[0] - $RSSQLServer = $args[1] - $RSSQLInstanceName = $args[2] - $InstanceKey = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\RS" -Name $InstanceName).$InstanceName - $SQLVersion = ((Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$InstanceKey\Setup" -Name "Version").Version).Split(".")[0] - $DBCreateFile = [IO.Path]::GetTempFileName() - $DBRightsFile = [IO.Path]::GetTempFileName() - if($InstanceName -eq "MSSQLSERVER") - { - $RSServiceName = "ReportServer" - $RSVirtualDirectory = "ReportServer" - $RMVirtualDirectory = "Reports" - $RSDatabase = "ReportServer" - } - else - { - $RSServiceName = "ReportServer`$$InstanceName" - $RSVirtualDirectory = "ReportServer_$InstanceName" - $RMVirtualDirectory = "Reports_$InstanceName" - $RSDatabase = "ReportServer`$$InstanceName" - } - if($RSSQLInstanceName -eq "MSSQLSERVER") - { - $RSConnection = "$RSSQLServer" - } - else - { - $RSConnection = "$RSSQLServer\$RSSQLInstanceName" - } - $Language = (Get-WMIObject -Class Win32_OperatingSystem -Namespace root/cimv2 -ErrorAction SilentlyContinue).OSLanguage - $RSConfig = Get-WmiObject -Class MSReportServer_ConfigurationSetting -Namespace "root\Microsoft\SQLServer\ReportServer\RS_$InstanceName\v$SQLVersion\Admin" - if($RSConfig.VirtualDirectoryReportServer -ne $RSVirtualDirectory) - { - $RSConfig.SetVirtualDirectory("ReportServerWebService",$RSVirtualDirectory,$Language) - $RSConfig.ReserveURL("ReportServerWebService","http://+:80",$Language) - } - if($RSConfig.VirtualDirectoryReportManager -ne $RMVirtualDirectory) - { - $RSConfig.SetVirtualDirectory("ReportManager",$RMVirtualDirectory,$Language) - $RSConfig.ReserveURL("ReportManager","http://+:80",$Language) - } - $RSScript = $RSConfig.GenerateDatabaseCreationScript($RSDatabase,$Language,$false) - $RSScript.Script | Out-File $DBCreateFile - - # Determine RS service account - $RSSvcAccountUsername = (Get-WmiObject -Class Win32_Service | Where-Object {$_.Name -eq $RSServiceName}).StartName - if(($RSSvcAccountUsername -eq "LocalSystem") -or (($RSSvcAccountUsername.Length -ge 10) -and ($RSSvcAccountUsername.SubString(0,10) -eq "NT Service"))) - { - $RSSvcAccountUsername = $RSConfig.MachineAccountIdentity - } - $RSScript = $RSConfig.GenerateDatabaseRightsScript($RSSvcAccountUsername,$RSDatabase,$false,$true) - $RSScript.Script | Out-File $DBRightsFile - - # Get path to sqlcmd.exe - $SQLCmdLocations = @( - @{ - Key = "4B5EB208A08862C4C9A0A2924D2613FF" - Name = "BAF8FF4572ED7814281FBEEAA6EE68A9" - } - @{ - Key = "4B5EB208A08862C4C9A0A2924D2613FF" - Name = "2BE7307A359F21B48B3491F5D489D81A" - } - @{ - Key = "4B5EB208A08862C4C9A0A2924D2613FF" - Name = "17E375D97701E7C44BBDE4225A2D4BB8" - } - @{ - Key = "A4A2A5C7B23E40145A6AFA7667643E85" - Name = "8B035CCA4B6B6D045BB9514286FC740D" - } - ) - $SQLCmdPath = "" - foreach($SQLCmdLocation in $SQLCmdLocations) - { - if($SQLCmdPath -eq "") - { - if(Get-ItemProperty -Path ("HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\" + $SQLCmdLocation.Key) -Name $SQLCmdLocation.Name -ErrorAction SilentlyContinue) - { - - if(Test-Path -Path (Get-ItemProperty -Path ("HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\" + $SQLCmdLocation.Key) -Name $SQLCmdLocation.Name).($SQLCmdLocation.Name)) - { - $SQLCmdPath = (Get-ItemProperty -Path ("HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Installer\UserData\S-1-5-18\Components\" + $SQLCmdLocation.Key) -Name $SQLCmdLocation.Name).($SQLCmdLocation.Name) - } - } - } - } - if($SQLCmdPath -ne "") - { - & "$SQLCmdPath" -S $RSConnection -i $DBCreateFile - & "$SQLCmdPath" -S $RSConnection -i $DBRightsFile - $RSConfig.SetDatabaseConnection($RSConnection,$RSDatabase,2,"","") - $RSConfig.InitializeReportServer($RSConfig.InstallationID) - } - - Remove-Item -Path $DBCreateFile - Remove-Item -Path $DBRightsFile - } -ArgumentList @($InstanceName,$RSSQLServer,$RSSQLInstanceName) - } - - if(!(Test-TargetResource @PSBoundParameters)) - { - throw New-TerminatingError -ErrorType TestFailedAfterSet -ErrorCategory InvalidResult - } -} - - -function Test-TargetResource -{ - [CmdletBinding()] - [OutputType([System.Boolean])] - param - ( - [parameter(Mandatory = $true)] - [System.String] - $InstanceName, - - [parameter(Mandatory = $true)] - [System.String] - $RSSQLServer, - - [parameter(Mandatory = $true)] - [System.String] - $RSSQLInstanceName, - - [parameter(Mandatory = $true)] - [System.Management.Automation.PSCredential] - $SQLAdminCredential - ) - - $result = (Get-TargetResource @PSBoundParameters).IsInitialized - - $result -} - - -Export-ModuleMember -Function *-TargetResource diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerRSConfig/MSFT_xSQLServerRSConfig.schema.mof b/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerRSConfig/MSFT_xSQLServerRSConfig.schema.mof deleted file mode 100644 index 5891a288e..000000000 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerRSConfig/MSFT_xSQLServerRSConfig.schema.mof +++ /dev/null @@ -1,9 +0,0 @@ -[ClassVersion("1.0.0.0"), FriendlyName("xSQLServerRSConfig")] -class MSFT_xSQLServerRSConfig : OMI_BaseResource -{ - [Key, Description("Name of the SQL Server Reporting Services instance to be configured.")] String InstanceName; - [Required, Description("Name of the SQL Server to host the Reporting Service database.")] String RSSQLServer; - [Required, Description("Name of the SQL Server instance to host the Reporting Service database.")] String RSSQLInstanceName; - [Required, EmbeddedInstance("MSFT_Credential"), Description("Credential to be used to perform the configuration.")] String SQLAdminCredential; - [Read, Description("Is the Reporting Services instance initialized.")] Boolean IsInitialized; -}; diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerRSSecureConnectionLevel/MSFT_xSQLServerRSSecureConnectionLevel.psm1 b/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerRSSecureConnectionLevel/MSFT_xSQLServerRSSecureConnectionLevel.psm1 deleted file mode 100644 index 6771f2ad9..000000000 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerRSSecureConnectionLevel/MSFT_xSQLServerRSSecureConnectionLevel.psm1 +++ /dev/null @@ -1,114 +0,0 @@ -$currentPath = Split-Path -Parent $MyInvocation.MyCommand.Path -Write-Debug -Message "CurrentPath: $currentPath" - -# Load Common Code -Import-Module $currentPath\..\..\xSQLServerHelper.psm1 -Verbose:$false -ErrorAction Stop - -function Get-TargetResource -{ - [CmdletBinding()] - [OutputType([System.Collections.Hashtable])] - param - ( - [parameter(Mandatory = $true)] - [System.String] - $InstanceName, - - [parameter(Mandatory = $true)] - [System.UInt16] - $SecureConnectionLevel, - - [parameter(Mandatory = $true)] - [System.Management.Automation.PSCredential] - $SQLAdminCredential - ) - - if(Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\RS" -Name $InstanceName -ErrorAction SilentlyContinue) - { - $InstanceKey = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\RS" -Name $InstanceName).$InstanceName - $SQLVersion = ((Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$InstanceKey\Setup" -Name "Version").Version).Split(".")[0] - $SecureConnectionLevel = Invoke-Command -ComputerName . -Credential $SQLAdminCredential -ScriptBlock { - $SQLVersion = $args[0] - $InstanceName = $args[1] - $RSConfig = Get-WmiObject -Class MSReportServer_ConfigurationSetting -Namespace "root\Microsoft\SQLServer\ReportServer\RS_$InstanceName\v$SQLVersion\Admin" - $RSConfig.SecureConnectionLevel - } -ArgumentList @($SQLVersion,$InstanceName) - } - else - { - throw New-TerminatingError -ErrorType SSRSNotFound -FormatArgs @($InstanceName) -ErrorCategory ObjectNotFound - } - - $returnValue = @{ - InstanceName = $InstanceName - SecureConnectionLevel = $SecureConnectionLevel - } - - $returnValue -} - - -function Set-TargetResource -{ - [CmdletBinding()] - param - ( - [parameter(Mandatory = $true)] - [System.String] - $InstanceName, - - [parameter(Mandatory = $true)] - [System.UInt16] - $SecureConnectionLevel, - - [parameter(Mandatory = $true)] - [System.Management.Automation.PSCredential] - $SQLAdminCredential - ) - - if(Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\RS" -Name $InstanceName -ErrorAction SilentlyContinue) - { - $InstanceKey = (Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\Instance Names\RS" -Name $InstanceName).$InstanceName - $SQLVersion = ((Get-ItemProperty -Path "HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server\$InstanceKey\Setup" -Name "Version").Version).Split(".")[0] - Invoke-Command -ComputerName . -Credential $SQLAdminCredential -ScriptBlock { - $SQLVersion = $args[0] - $InstanceName = $args[1] - $SecureConnectionLevel = $args[2] - $RSConfig = Get-WmiObject -Class MSReportServer_ConfigurationSetting -Namespace "root\Microsoft\SQLServer\ReportServer\RS_$InstanceName\v$SQLVersion\Admin" - $RSConfig.SetSecureConnectionLevel($SecureConnectionLevel) - } -ArgumentList @($SQLVersion,$InstanceName,$SecureConnectionLevel) - } - - if(!(Test-TargetResource @PSBoundParameters)) - { - throw New-TerminatingError -ErrorType TestFailedAfterSet -ErrorCategory InvalidResult - } -} - - -function Test-TargetResource -{ - [CmdletBinding()] - [OutputType([System.Boolean])] - param - ( - [parameter(Mandatory = $true)] - [System.String] - $InstanceName, - - [parameter(Mandatory = $true)] - [System.UInt16] - $SecureConnectionLevel, - - [parameter(Mandatory = $true)] - [System.Management.Automation.PSCredential] - $SQLAdminCredential - ) - - $result = ((Get-TargetResource @PSBoundParameters).SecureConnectionLevel -eq $SecureConnectionLevel) - - $result -} - - -Export-ModuleMember -Function *-TargetResource diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerRSSecureConnectionLevel/MSFT_xSQLServerRSSecureConnectionLevel.schema.mof b/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerRSSecureConnectionLevel/MSFT_xSQLServerRSSecureConnectionLevel.schema.mof deleted file mode 100644 index 9539097ed..000000000 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xSQLServerRSSecureConnectionLevel/MSFT_xSQLServerRSSecureConnectionLevel.schema.mof +++ /dev/null @@ -1,7 +0,0 @@ -[ClassVersion("1.0.0.0"), FriendlyName("xSQLServerRSSecureConnectionLevel")] -class MSFT_xSQLServerRSSecureConnectionLevel : OMI_BaseResource -{ - [Key, Description("SQL instance to set secure connection level for.")] String InstanceName; - [Key, Description("SQL Server Reporting Service secure connection level.")] Uint16 SecureConnectionLevel; - [Required, EmbeddedInstance("MSFT_Credential"), Description("Credential with administrative permissions to the SQL instance.")] String SQLAdminCredential; -}; diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xWaitForAvailabilityGroup/MSFT_xWaitForAvailabilityGroup.psm1 b/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xWaitForAvailabilityGroup/MSFT_xWaitForAvailabilityGroup.psm1 deleted file mode 100644 index 323889edb..000000000 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xWaitForAvailabilityGroup/MSFT_xWaitForAvailabilityGroup.psm1 +++ /dev/null @@ -1,126 +0,0 @@ -$currentPath = Split-Path -Parent $MyInvocation.MyCommand.Path -Write-Verbose -Message "CurrentPath: $currentPath" - -# Load Common Code -Import-Module $currentPath\..\..\xSQLServerHelper.psm1 -Verbose:$false -ErrorAction Stop - -function Get-TargetResource -{ - [CmdletBinding()] - [OutputType([System.Collections.Hashtable])] - param - ( - [parameter(Mandatory = $true)] - [System.String] - $Name, - - [UInt64] $RetryIntervalSec = 10, - [UInt32] $RetryCount = 50 - ) - - @{ - Name = $Name - RetryIntervalSec = $RetryIntervalSec - RetryCount = $RetryCount - } -} - - -function Set-TargetResource -{ - [CmdletBinding()] - param - ( - [parameter(Mandatory = $true)] - [System.String] - $Name, - - [System.UInt64] - $RetryIntervalSec =20, - - [System.UInt32] - $RetryCount = 6 - ) - - $AGFound = $false - New-VerboseMessage -Message "Checking for Availaibilty Group $Name ..." - - for ($count = 0; $count -lt $RetryCount; $count++) - { - try - { - $clusterGroup = Get-ClusterGroup -Name $Name -ErrorAction Ignore - - if ($clusterGroup -ne $null) - { - New-VerboseMessage -Message "Found Availability Group $Name" - $AGFound = $true - Start-Sleep -Seconds $RetryIntervalSec - break; - } - - } - catch - { - New-VerboseMessage -Message "Availability Group $Name not found. Will retry again after $RetryIntervalSec sec" - } - - New-VerboseMessage -Message "Availability Group $Name not found. Will retry again after $RetryIntervalSec sec" - Start-Sleep -Seconds $RetryIntervalSec - } - - if (! $AGFound) - { - throw "Availability Group $Name not found after $count attempts with $RetryIntervalSec sec interval" - Exit - } - - -} - - -function Test-TargetResource -{ - [CmdletBinding()] - [OutputType([System.Boolean])] - param - ( - [parameter(Mandatory = $true)] - [System.String] - $Name, - - [System.UInt64] - $RetryIntervalSec = 10, - - [System.UInt32] - $RetryCount = 50 - ) - - New-VerboseMessage -Message "Checking for Availability Group $Name ..." - - try - { - - $clusterGroup = Get-ClusterGroup -Name $Name -ErrorAction Ignore - - if ($clusterGroup -eq $null) - { - New-VerboseMessage -Message "Availability Group $Name not found" - $false - } - else - { - New-VerboseMessage -Message "Found Availabilty Group $Name" - $true - } - } - catch - { - New-VerboseMessage -Message "Availability Group $Name not found" - $false - } -} - - -Export-ModuleMember -Function *-TargetResource - diff --git a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xWaitForAvailabilityGroup/MSFT_xWaitForAvailabilityGroup.schema.mof b/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xWaitForAvailabilityGroup/MSFT_xWaitForAvailabilityGroup.schema.mof deleted file mode 100644 index 08be80882..000000000 --- a/lib/puppet_x/dsc_resources/xSQLServer/DSCResources/MSFT_xWaitForAvailabilityGroup/MSFT_xWaitForAvailabilityGroup.schema.mof +++ /dev/null @@ -1,9 +0,0 @@ - -[ClassVersion("1.0.0.0"), FriendlyName("xWaitForAvailabilityGroup")] -class MSFT_xWaitForAvailabilityGroup : OMI_BaseResource -{ - [Key, Description("Availability Group Name")] String Name; - [Write, Description("Interval to check for Availability Group")] Uint64 RetryIntervalSec; - [Write, Description("Maximum number of retries to check Availabilty group creation")] Uint32 RetryCount; -}; - diff --git a/lib/puppet_x/dsc_resources/xSQLServer/en-US/xPDT.strings.psd1 b/lib/puppet_x/dsc_resources/xSQLServer/en-US/xPDT.strings.psd1 deleted file mode 100644 index 0411cbba1..000000000 --- a/lib/puppet_x/dsc_resources/xSQLServer/en-US/xPDT.strings.psd1 +++ /dev/null @@ -1,11 +0,0 @@ -ConvertFrom-StringData @' -###PSLOC -FileNotFound=File not found in the environment path -AbsolutePathOrFileName=Absolute path or file name expected -InvalidArgument=Invalid argument: '{0}' with value: '{1}' -InvalidArgumentAndMessage={0} {1} -ErrorStarting=Failure starting process matching path '{0}'. Message: {1} -FailureWaitingForProcessesToStart=Failed to wait for processes to start -ProcessStarted=Process matching path '{0}' started in process ID {1} -ProcessAlreadyStarted=Process matching path '{0}' already started in process ID {1} -'@ diff --git a/lib/puppet_x/dsc_resources/xSQLServer/en-US/xSQLServer.strings.psd1 b/lib/puppet_x/dsc_resources/xSQLServer/en-US/xSQLServer.strings.psd1 deleted file mode 100644 index 5313b446c..000000000 --- a/lib/puppet_x/dsc_resources/xSQLServer/en-US/xSQLServer.strings.psd1 +++ /dev/null @@ -1,114 +0,0 @@ -ConvertFrom-StringData @' -###PSLOC -# Common -NoKeyFound = No Localization key found for ErrorType: '{0}'. -AbsentNotImplemented = Ensure = Absent is not implemented! -TestFailedAfterSet = Test-TargetResource returned false after calling set. -RemoteConnectionFailed = Remote PowerShell connection to Server '{0}' failed. -TODO = ToDo. Work not implemented at this time. -UnexpectedErrorFromGet = Got unexpected result from Get-TargetResource. No change is made. -FailedToImportSqlModule = Failed to import {0} module. -SqlModuleNotFound = Neither SqlServer module or SQLPS module was found. -NotConnectedToInstance = Was unable to connect to the instance '{0}\\{1}' -AlterAvailabilityGroupFailed = Failed to alter the availability group '{0}'. -HadrNotEnabled = HADR is not enabled. -AvailabilityGroupNotFound = Unable to locate the availability group '{0}' on the instance '{1}'. - -# SQLServer -NoDatabase = Database '{0}' does not exist on SQL server '{1}\\{2}'. -SSRSNotFound = SQL Reporting Services instance '{0}' does not exist! -RoleNotFound = Role '{0}' does not exist on database '{1}' on SQL server '{2}\\{3}'." -LoginNotFound = Login '{0}' does not exist on SQL server '{1}\\{2}'." -FailedLogin = Creating a login of type 'SqlLogin' requires LoginCredential -FeatureNotSupported = '{0}' is not a valid value for setting 'FEATURES'. Refer to SQL Help for more information. - -# Database Role -AddLoginDatabaseSetError = Failed adding the login {2} as a user of the database {3}, on the instance {0}\\{1}. -DropMemberDatabaseSetError = Failed removing the login {2} from the role {3} on the database {4}, on the instance {0}\\{1}. -AddMemberDatabaseSetError = Failed adding the login {2} to the role {3} on the database {4}, on the instance {0}\\{1}. - -# AvailabilityGroupListener -AvailabilityGroupListenerNotFound = Trying to make a change to a listener that does not exist. -AvailabilityGroupListenerErrorVerifyExist = Unexpected result when trying to verify existence of listener '{0}'. -AvailabilityGroupListenerIPChangeError = IP-address configuration mismatch. Expecting '{0}' found '{1}'. Resource does not support changing IP-address. Listener needs to be removed and then created again. -AvailabilityGroupListenerDHCPChangeError = IP-address configuration mismatch. Expecting '{0}' found '{1}'. Resource does not support changing between static IP and DHCP. Listener needs to be removed and then created again. - -# Endpoint -EndpointNotFound = Endpoint '{0}' does not exist -EndpointErrorVerifyExist = Unexpected result when trying to verify existence of endpoint '{0}'. -EndpointFoundButWrongType = Endpoint '{0}' does exist, but it is not of type 'DatabaseMirroring'. - -# Permission -PermissionGetError = Unexpected result when trying to get permissions for '{0}'. -PrincipalNotFound = Principal '{0}' does not exist. -PermissionMissingEnsure = Ensure is not set. No change can be made. - -# Configuration -ConfigurationOptionNotFound = Specified option '{0}' could not be found. -ConfigurationRestartRequired = Configuration option '{0}' has been updated, but a manual restart of SQL Server is required for it to take effect. - -# AlwaysOnService -AlterAlwaysOnServiceFailed = Failed to ensure Always On is {0} on the instance '{1}'. - -# Login -PasswordValidationFailed = Creation of the login '{0}' failed due to the following error: {1} -LoginCreationFailedFailedOperation = Creation of the login '{0}' failed due to a failed operation. -LoginCreationFailedSqlNotSpecified = Creation of the SQL login '{0}' failed due to an unspecified error. -LoginCreationFailedWindowsNotSpecified = Creation of the Windows login '{0}' failed due to an unspecified error. -LoginTypeNotImplemented = The login type '{0}' is not implemented in this resource. -IncorrectLoginMode = The instance '{0}\{1}' is currently in '{2}' authentication mode. To create a SQL Login, it must be set to 'Mixed' authentication mode. -LoginCredentialNotFound = The credential for the SQL Login '{0}' was not found. -PasswordChangeFailed = Setting the password failed for the SQL Login '{0}'. -AlterLoginFailed = Altering the login '{0}' failed. -CreateLoginFailed = Creating the login '{0}' failed. -DropLoginFailed = Dropping the login '{0}' failed. - -# Clustered Setup -FailoverClusterDiskMappingError = Unable to map the specified paths to valid cluster storage. Drives mapped: {0} -FailoverClusterIPAddressNotValid = Unable to map the specified IP Address(es) to valid cluster networks. -FailoverClusterResourceNotFound = Could not locate a SQL Server cluster resource for instance {0}. - -# AlwaysOnAvailabilityGroup -AlterAvailabilityGroupReplicaFailed = Failed to alter the avilability group replica '{0}'. -ClusterPermissionsMissing = The cluster does not have permissions to manage the Availability Group on '{0}\\{1}'. Grant 'Connect SQL', 'Alter Any Availability Group', and 'View Server State' to either 'NT SERVICE\\ClusSvc' or 'NT AUTHORITY\\SYSTEM'. -CreateAvailabilityGroupReplicaFailed = Creating the Availability Group Replica failed. -CreateAvailabilityGroupFailed = Creating the availability group '{0}' failed with the error '{1}'. -DatabaseMirroringEndpointNotFound = No database mirroring endpoint was found on '{0}\{1}'. -InstanceNotPrimaryReplica = The instance '{0}' is not the primary replica for the availability group '{1}'. -RemoveAvailabilityGroupFailed = Failed to remove the availabilty group '{0}' from the '{1}' instance. - -# AlwaysOnAvailabilityGroupReplica -JoinAvailabilityGroupFailed = Failed to join the availability group replica '{0}'. -RemoveAvailabilityGroupReplicaFailed = Failed to remove the availability group replica '{0}' with the error '{1}'. -ReplicaNotFound = Unable to find the availability group replica '{0}' on the instance '{1}'. - -# SQLServerHelper -ExecuteQueryWithResultsFailed = Executing query with results failed on database '{0}'. -ExecuteNonQueryFailed = Executing non-query failed on database '{0}'. -AnalysisServicesFailedToConnect = Failed to connect to Analysis Services '{0}'. -AnalysisServicesNoServerObject = Did not get the expected Analysis Services server object. - -# Max degree of parallelism -MaxDopSetError = Unexpected result when trying to configure the max degree of parallelism server configuration option. -MaxDopParamMustBeNull = MaxDop parameter must be set to $null or not assigned if DynamicAlloc parameter is set to $true. - -# Server Memory -MaxMemoryParamMustBeNull = The parameter MaxMemory must be null when DynamicAlloc is set to true. -MaxMemoryParamMustNotBeNull = The parameter MaxMemory must not be null when DynamicAlloc is set to false. -AlterServerMemoryFailed = Failed to alter the server configuration memory for {0}\\{1}. -ErrorGetDynamicMaxMemory = Failed to calculate dynamically the maximum memory. - -# SQLServerDatabase -CreateDatabaseSetError = Failed to create the database named {2} on {0}\\{1}. -DropDatabaseSetError = Failed to drop the database named {2} on {0}\\{1}. -FailedToGetOwnerDatabase = Failed to get owner of the database named {0} on {1}\\{2}. -FailedToSetOwnerDatabase = Failed to set owner named {0} of the database named {1} on {2}\\{3}. - -# SQLServerRole -EnumMemberNamesServerRoleGetError = Failed to enumerate members of the server role named {2} on {0}\\{1}. -MembersToIncludeAndExcludeParamMustBeNull = The parameter MembersToInclude and/or MembersToExclude must not be set, or be set to $null, when parameter Members are used. -CreateServerRoleSetError = Failed to create the server role named {2} on {0}\\{1}. -DropServerRoleSetError = Failed to drop the server role named {2} on {0}\\{1}. -AddMemberServerRoleSetError = Failed to add member {3} to the server role named {2} on {0}\\{1}. -DropMemberServerRoleSetError = Failed to drop member {3} to the server role named {2} on {0}\\{1}. -'@ diff --git a/lib/puppet_x/dsc_resources/xSQLServer/xPDT.psm1 b/lib/puppet_x/dsc_resources/xSQLServer/xPDT.psm1 deleted file mode 100644 index 6334ef1a4..000000000 --- a/lib/puppet_x/dsc_resources/xSQLServer/xPDT.psm1 +++ /dev/null @@ -1,708 +0,0 @@ -Import-LocalizedData LocalizedData -filename xPDT.strings.psd1 - -function ThrowInvalidArgumentError -{ - [CmdletBinding()] - param - ( - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [String] - $errorId, - - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [String] - $errorMessage - ) - - $errorCategory=[System.Management.Automation.ErrorCategory]::InvalidArgument - $exception = New-Object System.ArgumentException $errorMessage; - $errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, $errorId, $errorCategory, $null - throw $errorRecord -} - -function ResolvePath -{ - [CmdletBinding()] - param - ( - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [System.String] - $Path - ) - - $Path = [Environment]::ExpandEnvironmentVariables($Path) - if(IsRootedPath $Path) - { - if(!(Test-Path $Path -PathType Leaf)) - { - ThrowInvalidArgumentError "CannotFindRootedPath" ($LocalizedData.InvalidArgumentAndMessage -f ($LocalizedData.InvalidArgument -f "Path",$Path), $LocalizedData.FileNotFound) - } - return $Path - } - else - { - $Path = (Get-Item -Path $Path -ErrorAction SilentlyContinue).FullName - if(!(Test-Path $Path -PathType Leaf)) - { - ThrowInvalidArgumentError "CannotFindRootedPath" ($LocalizedData.InvalidArgumentAndMessage -f ($LocalizedData.InvalidArgument -f "Path",$Path), $LocalizedData.FileNotFound) - } - return $Path - } - if([string]::IsNullOrEmpty($env:Path)) - { - ThrowInvalidArgumentError "EmptyEnvironmentPath" ($LocalizedData.InvalidArgumentAndMessage -f ($LocalizedData.InvalidArgument -f "Path",$Path), $LocalizedData.FileNotFound) - } - if((Split-Path $Path -Leaf) -ne $Path) - { - ThrowInvalidArgumentError "NotAbsolutePathOrFileName" ($LocalizedData.InvalidArgumentAndMessage -f ($LocalizedData.InvalidArgument -f "Path",$Path), $LocalizedData.AbsolutePathOrFileName) - } - foreach($rawSegment in $env:Path.Split(";")) - { - $segment = [Environment]::ExpandEnvironmentVariables($rawSegment) - $segmentRooted = $false - try - { - $segmentRooted=[IO.Path]::IsPathRooted($segment) - } - catch {} - if(!$segmentRooted) - { - continue - } - $candidate = join-path $segment $Path - if(Test-Path $candidate -PathType Leaf) - { - return $candidate - } - } - ThrowInvalidArgumentError "CannotFindRelativePath" ($LocalizedData.InvalidArgumentAndMessage -f ($LocalizedData.InvalidArgument -f "Path",$Path), $LocalizedData.FileNotFound) -} - -function IsRootedPath -{ - param - ( - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [String] - $Path - ) - - try - { - return [IO.Path]::IsPathRooted($Path) - } - catch - { - ThrowInvalidArgumentError "CannotGetIsPathRooted" ($LocalizedData.InvalidArgumentAndMessage -f ($LocalizedData.InvalidArgument -f "Path",$Path), $_.Exception.Message) - } -} - -function ExtractArguments -{ - [CmdletBinding()] - param - ( - [parameter(Mandatory = $true)] - $functionBoundParameters, - - [parameter(Mandatory = $true)] - [string[]] - $argumentNames, - - [string[]] - $newArgumentNames - ) - - $returnValue=@{} - - for($i=0;$i -lt $argumentNames.Count;$i++) - { - $argumentName = $argumentNames[$i] - - if($newArgumentNames -eq $null) - { - $newArgumentName = $argumentName - } - else - { - $newArgumentName = $newArgumentNames[$i] - } - - if($functionBoundParameters.ContainsKey($argumentName)) - { - $null = $returnValue.Add($newArgumentName,$functionBoundParameters[$argumentName]) - } - } - - return $returnValue -} - -function CallPInvoke -{ - $script:ProgramSource = @" -using System; -using System.Collections.Generic; -using System.Text; -using System.Security; -using System.Runtime.InteropServices; -using System.Diagnostics; -using System.Security.Principal; -using System.ComponentModel; -using System.IO; - -namespace Source -{ - [SuppressUnmanagedCodeSecurity] - public static class NativeMethods - { - //The following structs and enums are used by the various Win32 API's that are used in the code below - - [StructLayout(LayoutKind.Sequential)] - public struct STARTUPINFO - { - public Int32 cb; - public string lpReserved; - public string lpDesktop; - public string lpTitle; - public Int32 dwX; - public Int32 dwY; - public Int32 dwXSize; - public Int32 dwXCountChars; - public Int32 dwYCountChars; - public Int32 dwFillAttribute; - public Int32 dwFlags; - public Int16 wShowWindow; - public Int16 cbReserved2; - public IntPtr lpReserved2; - public IntPtr hStdInput; - public IntPtr hStdOutput; - public IntPtr hStdError; - } - - [StructLayout(LayoutKind.Sequential)] - public struct PROCESS_INFORMATION - { - public IntPtr hProcess; - public IntPtr hThread; - public Int32 dwProcessID; - public Int32 dwThreadID; - } - - [Flags] - public enum LogonType - { - LOGON32_LOGON_INTERACTIVE = 2, - LOGON32_LOGON_NETWORK = 3, - LOGON32_LOGON_BATCH = 4, - LOGON32_LOGON_SERVICE = 5, - LOGON32_LOGON_UNLOCK = 7, - LOGON32_LOGON_NETWORK_CLEARTEXT = 8, - LOGON32_LOGON_NEW_CREDENTIALS = 9 - } - - [Flags] - public enum LogonProvider - { - LOGON32_PROVIDER_DEFAULT = 0, - LOGON32_PROVIDER_WINNT35, - LOGON32_PROVIDER_WINNT40, - LOGON32_PROVIDER_WINNT50 - } - - [StructLayout(LayoutKind.Sequential)] - public struct SECURITY_ATTRIBUTES - { - public Int32 Length; - public IntPtr lpSecurityDescriptor; - public bool bInheritHandle; - } - - public enum SECURITY_IMPERSONATION_LEVEL - { - SecurityAnonymous, - SecurityIdentification, - SecurityImpersonation, - SecurityDelegation - } - - public enum TOKEN_TYPE - { - TokenPrimary = 1, - TokenImpersonation - } - - [StructLayout(LayoutKind.Sequential, Pack = 1)] - internal struct TokPriv1Luid - { - public int Count; - public long Luid; - public int Attr; - } - - public const int GENERIC_ALL_ACCESS = 0x10000000; - public const int CREATE_NO_WINDOW = 0x08000000; - internal const int SE_PRIVILEGE_ENABLED = 0x00000002; - internal const int TOKEN_QUERY = 0x00000008; - internal const int TOKEN_ADJUST_PRIVILEGES = 0x00000020; - internal const string SE_INCRASE_QUOTA = "SeIncreaseQuotaPrivilege"; - - [DllImport("kernel32.dll", - EntryPoint = "CloseHandle", SetLastError = true, - CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)] - public static extern bool CloseHandle(IntPtr handle); - - [DllImport("advapi32.dll", - EntryPoint = "CreateProcessAsUser", SetLastError = true, - CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] - public static extern bool CreateProcessAsUser( - IntPtr hToken, - string lpApplicationName, - string lpCommandLine, - ref SECURITY_ATTRIBUTES lpProcessAttributes, - ref SECURITY_ATTRIBUTES lpThreadAttributes, - bool bInheritHandle, - Int32 dwCreationFlags, - IntPtr lpEnvrionment, - string lpCurrentDirectory, - ref STARTUPINFO lpStartupInfo, - ref PROCESS_INFORMATION lpProcessInformation - ); - - [DllImport("advapi32.dll", EntryPoint = "DuplicateTokenEx")] - public static extern bool DuplicateTokenEx( - IntPtr hExistingToken, - Int32 dwDesiredAccess, - ref SECURITY_ATTRIBUTES lpThreadAttributes, - Int32 ImpersonationLevel, - Int32 dwTokenType, - ref IntPtr phNewToken - ); - - [DllImport("advapi32.dll", CharSet = CharSet.Unicode, SetLastError = true)] - public static extern Boolean LogonUser( - String lpszUserName, - String lpszDomain, - String lpszPassword, - LogonType dwLogonType, - LogonProvider dwLogonProvider, - out IntPtr phToken - ); - - [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)] - internal static extern bool AdjustTokenPrivileges( - IntPtr htok, - bool disall, - ref TokPriv1Luid newst, - int len, - IntPtr prev, - IntPtr relen - ); - - [DllImport("kernel32.dll", ExactSpelling = true)] - internal static extern IntPtr GetCurrentProcess(); - - [DllImport("advapi32.dll", ExactSpelling = true, SetLastError = true)] - internal static extern bool OpenProcessToken( - IntPtr h, - int acc, - ref IntPtr phtok - ); - - [DllImport("advapi32.dll", SetLastError = true)] - internal static extern bool LookupPrivilegeValue( - string host, - string name, - ref long pluid - ); - - public static void CreateProcessAsUser(string strCommand, string strDomain, string strName, string strPassword) - { - var hToken = IntPtr.Zero; - var hDupedToken = IntPtr.Zero; - TokPriv1Luid tp; - var pi = new PROCESS_INFORMATION(); - var sa = new SECURITY_ATTRIBUTES(); - sa.Length = Marshal.SizeOf(sa); - Boolean bResult = false; - try - { - bResult = LogonUser( - strName, - strDomain, - strPassword, - LogonType.LOGON32_LOGON_BATCH, - LogonProvider.LOGON32_PROVIDER_DEFAULT, - out hToken - ); - if (!bResult) - { - throw new Win32Exception("The user could not be logged on. Ensure that the user has an existing profile on the machine and that correct credentials are provided. Logon error #" + Marshal.GetLastWin32Error().ToString()); - } - IntPtr hproc = GetCurrentProcess(); - IntPtr htok = IntPtr.Zero; - bResult = OpenProcessToken( - hproc, - TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, - ref htok - ); - if(!bResult) - { - throw new Win32Exception("Open process token error #" + Marshal.GetLastWin32Error().ToString()); - } - tp.Count = 1; - tp.Luid = 0; - tp.Attr = SE_PRIVILEGE_ENABLED; - bResult = LookupPrivilegeValue( - null, - SE_INCRASE_QUOTA, - ref tp.Luid - ); - if(!bResult) - { - throw new Win32Exception("Error in looking up privilege of the process. This should not happen if DSC is running as LocalSystem Lookup privilege error #" + Marshal.GetLastWin32Error().ToString()); - } - bResult = AdjustTokenPrivileges( - htok, - false, - ref tp, - 0, - IntPtr.Zero, - IntPtr.Zero - ); - if(!bResult) - { - throw new Win32Exception("Token elevation error #" + Marshal.GetLastWin32Error().ToString()); - } - - bResult = DuplicateTokenEx( - hToken, - GENERIC_ALL_ACCESS, - ref sa, - (int)SECURITY_IMPERSONATION_LEVEL.SecurityIdentification, - (int)TOKEN_TYPE.TokenPrimary, - ref hDupedToken - ); - if(!bResult) - { - throw new Win32Exception("Duplicate Token error #" + Marshal.GetLastWin32Error().ToString()); - } - var si = new STARTUPINFO(); - si.cb = Marshal.SizeOf(si); - si.lpDesktop = ""; - bResult = CreateProcessAsUser( - hDupedToken, - null, - strCommand, - ref sa, - ref sa, - false, - 0, - IntPtr.Zero, - null, - ref si, - ref pi - ); - if(!bResult) - { - throw new Win32Exception("The process could not be created. Create process as user error #" + Marshal.GetLastWin32Error().ToString()); - } - } - finally - { - if (pi.hThread != IntPtr.Zero) - { - CloseHandle(pi.hThread); - } - if (pi.hProcess != IntPtr.Zero) - { - CloseHandle(pi.hProcess); - } - if (hDupedToken != IntPtr.Zero) - { - CloseHandle(hDupedToken); - } - } - } - } -} - -"@ - Add-Type -TypeDefinition $ProgramSource -ReferencedAssemblies "System.ServiceProcess" -} - -function GetWin32Process -{ - [CmdletBinding()] - param - ( - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [String] - $Path, - - [String] - $Arguments, - - [PSCredential] - $Credential - ) - - $fileName = [io.path]::GetFileNameWithoutExtension($Path) - $GetProcesses = @(Get-Process -Name $fileName -ErrorAction SilentlyContinue) - $Processes = foreach($process in $GetProcesses) - { - if($Process.Path -ieq $Path) - { - try - { - [wmi]"Win32_Process.Handle='$($Process.Id)'" - } - catch - { - } - } - } - if($PSBoundParameters.ContainsKey('Credential')) - { - $Processes = $Processes | Where-Object {(GetWin32ProcessOwner $_) -eq $Credential.UserName} - } - if($Arguments -eq $null) {$Arguments = ""} - $Processes = $Processes | Where-Object {(GetWin32ProcessArgumentsFromCommandLine $_.CommandLine) -eq $Arguments} - - return $Processes -} - -function GetWin32ProcessOwner -{ - param - ( - [parameter(Mandatory = $true)] - [ValidateNotNull()] - $Process - ) - - try - { - $Owner = $Process.GetOwner() - } - catch - {} - if(($owner.Domain -ne $null) -and ($owner.Domain -ne $env:COMPUTERNAME)) - { - return $Owner.Domain + "\" + $Owner.User - } - else - { - return $Owner.User - } -} - -function GetWin32ProcessArgumentsFromCommandLine -{ - param - ( - [String] - $commandLine - ) - - if($commandLine -eq $null) - { - return "" - } - $commandLine=$commandLine.Trim() - if($commandLine.Length -eq 0) - { - return "" - } - if($commandLine[0] -eq '"') - { - $charToLookfor=[char]'"' - } - else - { - $charToLookfor=[char]' ' - } - $endOfCommand=$commandLine.IndexOf($charToLookfor ,1) - if($endOfCommand -eq -1) - { - return "" - } - return $commandLine.Substring($endOfCommand+1).Trim() -} - -function StartWin32Process -{ - param - ( - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [String] - $Path, - - [String] - $Arguments, - - [PSCredential] - $Credential, - - [Switch] - $AsTask - ) - - $GetArguments = ExtractArguments $PSBoundParameters ("Path","Arguments","Credential") - $Processes = @(GetWin32Process @getArguments) - if ($processes.Count -eq 0) - { - if($PSBoundParameters.ContainsKey("Credential")) - { - if($AsTask) - { - $ActionArguments = ExtractArguments $PSBoundParameters ` - ("Path", "Arguments") ` - ("Execute", "Argument") - if([string]::IsNullOrEmpty($Arguments)) - { - $null = $ActionArguments.Remove("Argument") - } - $TaskGuid = [guid]::NewGuid().ToString() - $Action = New-ScheduledTaskAction @ActionArguments - $null = Register-ScheduledTask -TaskName "xPDT $TaskGuid" -Action $Action -User $Credential.UserName -Password $Credential.GetNetworkCredential().Password -RunLevel Highest - $err = Start-ScheduledTask -TaskName "xPDT $TaskGuid" - } - else - { - try - { - CallPInvoke - [Source.NativeMethods]::CreateProcessAsUser(("$Path " + $Arguments),$Credential.GetNetworkCredential().Domain,$Credential.GetNetworkCredential().UserName,$Credential.GetNetworkCredential().Password) - } - catch - { - $exception = New-Object System.ArgumentException $_ - $errorCategory = [System.Management.Automation.ErrorCategory]::OperationStopped - $errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, "Win32Exception", $errorCategory, $null - $err = $errorRecord - } - } - } - else - { - $StartArguments = ExtractArguments $PSBoundParameters ` - ("Path", "Arguments", "Credential") ` - ("FilePath", "ArgumentList", "Credential") - if([string]::IsNullOrEmpty($Arguments)) - { - $null = $StartArguments.Remove("ArgumentList") - } - $err = Start-Process @StartArguments - } - if($err -ne $null) - { - throw $err - } - if (!(WaitForWin32ProcessStart @GetArguments)) - { -# ThrowInvalidArgumentError "FailureWaitingForProcessesToStart" ($LocalizedData.ErrorStarting -f $Path,$LocalizedData.FailureWaitingForProcessesToStart) - } - } - else - { - return ($LocalizedData.ProcessAlreadyStarted -f $Path,$Processes.ProcessId) - } - $Processes = @(GetWin32Process @getArguments) - return ($LocalizedData.ProcessStarted -f $Path,$Processes.ProcessId) -} - -function WaitForWin32ProcessStart -{ - [CmdletBinding()] - param - ( - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [String] - $Path, - - [String] - $Arguments, - - [PSCredential] - $Credential, - - [Int] - $Delay = 60000 - ) - - $start = [DateTime]::Now - $GetArguments = ExtractArguments $PSBoundParameters ("Path","Arguments","Credential") - do - { - $value = @(GetWin32Process @GetArguments).Count -ge 1 - } while(!$value -and ([DateTime]::Now - $start).TotalMilliseconds -lt $Delay) - - return $value -} - -function WaitForWin32ProcessEnd -{ - [CmdletBinding()] - param - ( - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [String] - $Path, - - [String] - $Arguments, - - [PSCredential] - $Credential - ) - - $GetArguments = ExtractArguments $PSBoundParameters ("Path","Arguments","Credential") - While (WaitForWin32ProcessStart @GetArguments -Delay 1000) - { - Start-Sleep 1 - } - Get-ScheduledTask | Where-Object {($_.TaskName.StartsWith("xPDT")) -and ($_.Actions.Execute -eq $Path) -and ($_.Actions.Arguments -eq $Arguments)} | Where-Object {$_ -ne $null} | Unregister-ScheduledTask -Confirm:$false -} - -function NetUse -{ - param - ( - [parameter(Mandatory)] - [string] - $SourcePath, - - [parameter(Mandatory)] - [PSCredential] - $Credential, - - [string] - [ValidateSet("Present","Absent")] - $Ensure = "Present" - ) - - if(($SourcePath.Length -ge 2) -and ($SourcePath.Substring(0,2) -eq "\\")) - { - $args = @() - if ($Ensure -eq "Absent") - { - $args += "use", $SourcePath, "/del" - } - else - { - $args += "use", $SourcePath, $($Credential.GetNetworkCredential().Password), "/user:$($Credential.GetNetworkCredential().Domain)\$($Credential.GetNetworkCredential().UserName)" - } - - &"net" $args - } -} - -Export-ModuleMember ResolvePath,StartWin32Process,WaitForWin32ProcessEnd,NetUse diff --git a/lib/puppet_x/dsc_resources/xSQLServer/xSQLServer.psd1 b/lib/puppet_x/dsc_resources/xSQLServer/xSQLServer.psd1 deleted file mode 100644 index 83be64bb2..000000000 --- a/lib/puppet_x/dsc_resources/xSQLServer/xSQLServer.psd1 +++ /dev/null @@ -1,174 +0,0 @@ -@{ -# Version number of this module. -ModuleVersion = '7.0.0.0' - -# ID used to uniquely identify this module -GUID = '74e9ddb5-4cbc-4fa2-a222-2bcfb533fd66' - -# Author of this module -Author = 'Microsoft Corporation' - -# Company or vendor of this module -CompanyName = 'Microsoft Corporation' - -# Copyright statement for this module -Copyright = '(c) 2014 Microsoft Corporation. All rights reserved.' - -# Description of the functionality provided by this module -Description = 'Module with DSC Resources for deployment and configuration of Microsoft SQL Server.' - -# Minimum version of the Windows PowerShell engine required by this module -PowerShellVersion = '4.0' - -# Minimum version of the common language runtime (CLR) required by this module -CLRVersion = '4.0' - -# Functions to export from this module -FunctionsToExport = '*' - -# Cmdlets to export from this module -CmdletsToExport = '*' - -# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. -PrivateData = @{ - - PSData = @{ - - # Tags applied to this module. These help with module discovery in online galleries. - Tags = @('DesiredStateConfiguration', 'DSC', 'DSCResourceKit', 'DSCResource') - - # A URL to the license for this module. - LicenseUri = 'https://github.com/PowerShell/xSQLServer/blob/master/LICENSE' - - # A URL to the main website for this project. - ProjectUri = 'https://github.com/PowerShell/xSQLServer' - - # A URL to an icon representing this module. - # IconUri = '' - - # ReleaseNotes of this module - ReleaseNotes = '- Examples - - xSQLServerDatabaseRole - - 1-AddDatabaseRole.ps1 - - 2-RemoveDatabaseRole.ps1 - - xSQLServerRole - - 3-AddMembersToServerRole.ps1 - - 4-MembersToIncludeInServerRole.ps1 - - 5-MembersToExcludeInServerRole.ps1 - - xSQLServerSetup - - 1-InstallDefaultInstanceSingleServer.ps1 - - 2-InstallNamedInstanceSingleServer.ps1 - - 3-InstallNamedInstanceSingleServerFromUncPathUsingSourceCredential.ps1 - - 4-InstallNamedInstanceInFailoverClusterFirstNode.ps1 - - 5-InstallNamedInstanceInFailoverClusterSecondNode.ps1 - - xSQLServerReplication - - 1-ConfigureInstanceAsDistributor.ps1 - - 2-ConfigureInstanceAsPublisher.ps1 - - xSQLServerNetwork - - 1-EnableTcpIpOnCustomStaticPort.ps1 - - xSQLServerAvailabilityGroupListener - - 1-AddAvailabilityGroupListenerWithSameNameAsVCO.ps1 - - 2-AddAvailabilityGroupListenerWithDifferentNameAsVCO.ps1 - - 3-RemoveAvailabilityGroupListenerWithSameNameAsVCO.ps1 - - 4-RemoveAvailabilityGroupListenerWithDifferentNameAsVCO.ps1 - - 5-AddAvailabilityGroupListenerUsingDHCPWithDefaultServerSubnet.ps1 - - 6-AddAvailabilityGroupListenerUsingDHCPWithSpecificSubnet.ps1 - - xSQLServerEndpointPermission - - 1-AddConnectPermission.ps1 - - 2-RemoveConnectPermission.ps1 - - 3-AddConnectPermissionToAlwaysOnPrimaryAndSecondaryReplicaEachWithDifferentSqlServiceAccounts.ps1 - - 4-RemoveConnectPermissionToAlwaysOnPrimaryAndSecondaryReplicaEachWithDifferentSqlServiceAccounts.ps1 - - xSQLServerPermission - - 1-AddServerPermissionForLogin.ps1 - - 2-RemoveServerPermissionForLogin.ps1 - - xSQLServerEndpointState - - 1-MakeSureEndpointIsStarted.ps1 - - 2-MakeSureEndpointIsStopped.ps1 - - xSQLServerConfiguration - - 1-ConfigureTwoInstancesOnTheSameServerToEnableClr.ps1 - - 2-ConfigureInstanceToEnablePriorityBoost.ps1 - - xSQLServerEndpoint - - 1-CreateEndpointWithDefaultValues.ps1 - - 2-CreateEndpointWithSpecificPortAndIPAddress.ps1 - - 3-RemoveEndpoint.ps1 -- Changes to xSQLServerDatabaseRole - - Fixed code style, added updated parameter descriptions to schema.mof and README.md. -- Changes to xSQLServer - - Raised the CodeCov target to 70% which is the minimum and required target for HQRM resource. -- Changes to xSQLServerRole - - **BREAKING CHANGE: The resource has been reworked in it"s entirely.** Below is what has changed. - - The mandatory parameters now also include ServerRoleName. - - The ServerRole parameter was before an array of server roles, now this parameter is renamed to ServerRoleName and can only be set to one server role. - - ServerRoleName are no longer limited to built-in server roles. To add members to a built-in server role, set ServerRoleName to the name of the built-in server role. - - The ServerRoleName will be created when Ensure is set to "Present" (if it does not already exist), or removed if Ensure is set to "Absent". - - Three new parameters are added; Members, MembersToInclude and MembersToExclude. - - Members can be set to one or more logins, and those will _replace all_ the memberships in the server role. - - MembersToInclude and MembersToExclude can be set to one or more logins that will add or remove memberships, respectively, in the server role. MembersToInclude and MembersToExclude _can not_ be used at the same time as parameter Members. But both MembersToInclude and MembersToExclude can be used together at the same time. -- Changes to xSQLServerSetup - - Added a note to the README.md saying that it is not possible to add or remove features from a SQL Server failover cluster (issue 433). - - Changed so that it reports false if the desired state is not correct (issue 432). - - Added a test to make sure we always return false if a SQL Server failover cluster is missing features. - - Helper function Connect-SQLAnalysis - - Now has correct error handling, and throw does not used the unknown named parameter "-Message" (issue 436) - - Added tests for Connect-SQLAnalysis - - Changed to localized error messages. - - Minor changes to error handling. - - This adds better support for Addnode (issue 369). - - Now it skips cluster validation för add node (issue 442). - - Now it ignores parameters that are not allowed for action Addnode (issue 441). - - Added support for vNext CTP 1.4 (issue 472). -- Added new resource - - xSQLServerAlwaysOnAvailabilityGroupReplica -- Changes to xSQLServerDatabaseRecoveryModel - - Fixed code style, removed SQLServerDatabaseRecoveryModel functions from xSQLServerHelper. -- Changes to xSQLServerAlwaysOnAvailabilityGroup - - Fixed the permissions check loop so that it exits the loop after the function determines the required permissions are in place. -- Changes to xSQLServerAvailabilityGroupListener - - Removed the dependency of SQLPS provider (issue 460). - - Cleaned up code. - - Added test for more coverage. - - Fixed PSSA rule warnings (issue 255). - - Parameter Ensure now defaults to "Present" (issue 450). -- Changes to xSQLServerFirewall - - Now it will correctly create rules when the resource is used for two or more instances on the same server (issue 461). -- Changes to xSQLServerEndpointPermission - - Added description to the README.md - - Cleaned up code (issue 257 and issue 231) - - Now the default value for Ensure is "Present". - - Removed dependency of SQLPS provider (issue 483). - - Refactored tests so they use less code. -- Changes to README.md - - Adding deprecated tag to xSQLServerFailoverClusterSetup, xSQLAOGroupEnsure and xSQLAOGroupJoin in README.md so it it more clear that these resources has been replaced by xSQLServerSetup, xSQLServerAlwaysOnAvailabilityGroup and xSQLServerAlwaysOnAvailabilityGroupReplica respectively. -- Changes to xSQLServerEndpoint - - BREAKING CHANGE: Now SQLInstanceName is mandatory, and is a key, so SQLInstanceName has no longer a default value (issue 279). - - BREAKING CHANGE: Parameter AuthorizedUser has been removed (issue 466, issue 275 and issue 80). Connect permissions can be set using the resource xSQLServerEndpointPermission. - - Optional parameter IpAddress has been added. Default is to listen on any valid IP-address. (issue 232) - - Parameter Port now has a default value of 5022. - - Parameter Ensure now defaults to "Present". - - Resource now supports changing IP address and changing port. - - Added unit tests (issue 289) - - Added examples. -- Changes to xSQLServerEndpointState - - Cleaned up code, removed SupportsShouldProcess and fixed PSSA rules warnings (issue 258 and issue 230). - - Now the default value for the parameter State is "Started". - - Updated README.md with a description for the resources and revised the parameter descriptions. - - Removed dependency of SQLPS provider (issue 481). - - The parameter NodeName is no longer mandatory and has now the default value of $env:COMPUTERNAME. - - The parameter Name is now a key so it is now possible to change the state on more than one endpoint on the same instance. _Note: The resource still only supports Database Mirror endpoints at this time._ -- Changes to xSQLServerHelper module - - Removing helper function Get-SQLAlwaysOnEndpoint because there is no resource using it any longer. - - BREAKING CHANGE: Changed helper function Import-SQLPSModule to support SqlServer module (issue 91). The SqlServer module is the preferred module so if it is found it will be used, and if not found an attempt will be done to load SQLPS module instead. -- Changes to xSQLServerScript - - Updated tests for this resource, because they failed when Import-SQLPSModule was updated. -' - - } # End of PSData hashtable - -} # End of PrivateData hashtable -} - - - - - - diff --git a/lib/puppet_x/dsc_resources/xSQLServer/xSQLServerHelper.psm1 b/lib/puppet_x/dsc_resources/xSQLServer/xSQLServerHelper.psm1 deleted file mode 100644 index 110493f94..000000000 --- a/lib/puppet_x/dsc_resources/xSQLServer/xSQLServerHelper.psm1 +++ /dev/null @@ -1,1428 +0,0 @@ -# Load Localization Data -Import-LocalizedData LocalizedData -filename xSQLServer.strings.psd1 -ErrorAction SilentlyContinue -Import-LocalizedData USLocalizedData -filename xSQLServer.strings.psd1 -UICulture en-US -ErrorAction SilentlyContinue - -<# - .SYNOPSIS - Connect to a SQL Server Database Engine and return the server object. - - .PARAMETER SQLServer - String containing the host name of the SQL Server to connect to. - - .PARAMETER SQLInstanceName - String containing the SQL Server Database Engine instance to connect to. - - .PARAMETER SetupCredential - PSCredential object with the credentials to use to impersonate a user when connecting. - If this is not provided then the current user will be used to connect to the SQL Server Database Engine instance. -#> -function Connect-SQL -{ - [CmdletBinding()] - param - ( - [ValidateNotNull()] - [System.String] - $SQLServer = $env:COMPUTERNAME, - - [ValidateNotNull()] - [System.String] - $SQLInstanceName = "MSSQLSERVER", - - [ValidateNotNull()] - [System.Management.Automation.PSCredential] - $SetupCredential - ) - - $null = [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.Smo') - - if ($SQLInstanceName -eq "MSSQLSERVER") - { - $connectSql = $SQLServer - } - else - { - $connectSql = "$SQLServer\$SQLInstanceName" - } - - if ($SetupCredential) - { - $sql = New-Object Microsoft.SqlServer.Management.Smo.Server - $sql.ConnectionContext.ConnectAsUser = $true - $sql.ConnectionContext.ConnectAsUserPassword = $SetupCredential.GetNetworkCredential().Password - $sql.ConnectionContext.ConnectAsUserName = $SetupCredential.GetNetworkCredential().UserName - $sql.ConnectionContext.ServerInstance = $connectSQL - $sql.ConnectionContext.connect() - } - else - { - $sql = New-Object Microsoft.SqlServer.Management.Smo.Server $connectSql - } - - if (!$sql) - { - Throw -Message "Failed connecting to SQL $connectSql" - } - - New-VerboseMessage -Message "Connected to SQL $connectSql" - - return $sql -} - -<# - .SYNOPSIS - Connect to a SQL Server Analysis Service and return the server object. - - .PARAMETER SQLServer - String containing the host name of the SQL Server to connect to. - - .PARAMETER SQLInstanceName - String containing the SQL Server Analysis Service instance to connect to. - - .PARAMETER SetupCredential - PSCredential object with the credentials to use to impersonate a user when connecting. - If this is not provided then the current user will be used to connect to the SQL Server Analysis Service instance. -#> -function Connect-SQLAnalysis -{ - [CmdletBinding()] - param - ( - [Parameter()] - [ValidateNotNullOrEmpty()] - [System.String] - $SQLServer = $env:COMPUTERNAME, - - [Parameter()] - [ValidateNotNullOrEmpty()] - [System.String] - $SQLInstanceName = 'MSSQLSERVER', - - [Parameter()] - [ValidateNotNullOrEmpty()] - [System.Management.Automation.PSCredential] - [System.Management.Automation.Credential()] - $SetupCredential - ) - - $null = [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.AnalysisServices') - - if ($SQLInstanceName -eq 'MSSQLSERVER') - { - $analysisServiceInstance = $SQLServer - } - else - { - $analysisServiceInstance = "$SQLServer\$SQLInstanceName" - } - - if ($SetupCredential) - { - $userName = $SetupCredential.GetNetworkCredential().UserName - $password = $SetupCredential.GetNetworkCredential().Password - - $analysisServicesDataSource = "Data Source=$analysisServiceInstance;User ID=$userName;Password=$password" - } - else - { - $analysisServicesDataSource = "Data Source=$analysisServiceInstance" - } - - try - { - $analysisServicesObject = New-Object -TypeName Microsoft.AnalysisServices.Server - if ($analysisServicesObject) - { - $analysisServicesObject.Connect($analysisServicesDataSource) - } - else - { - throw New-TerminatingError -ErrorType AnalysisServicesNoServerObject -ErrorCategory InvalidResult - } - - Write-Verbose -Message "Connected to Analysis Services $analysisServiceInstance." -Verbose - } - catch - { - throw New-TerminatingError -ErrorType AnalysisServicesFailedToConnect -FormatArgs @($analysisServiceInstance) -ErrorCategory ObjectNotFound -InnerException $_.Exception - } - - return $analysisServicesObject -} - -<# - .SYNOPSIS - Returns a localized error message. - - .PARAMETER ErrorType - String containing the key of the localized error message. - - .PARAMETER FormatArgs - Collection of strings to replace format objects in the error message. - - .PARAMETER ErrorCategory - The category to use for the error message. Default value is 'OperationStopped'. - Valid values are a value from the enumeration System.Management.Automation.ErrorCategory. - - .PARAMETER TargetObject - The object that was being operated on when the error occurred. - - .PARAMETER InnerException - Exception object that was thorwn when the error occured, which will be added to the final error message. -#> -function New-TerminatingError -{ - [CmdletBinding()] - [OutputType([System.Management.Automation.ErrorRecord])] - param - ( - [Parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [String] - $ErrorType, - - [Parameter(Mandatory = $false)] - [String[]] - $FormatArgs, - - [Parameter(Mandatory = $false)] - [System.Management.Automation.ErrorCategory] - $ErrorCategory = [System.Management.Automation.ErrorCategory]::OperationStopped, - - [Parameter(Mandatory = $false)] - [Object] - $TargetObject = $null, - - [Parameter(Mandatory = $false)] - [System.Exception] - $InnerException = $null - ) - - $errorMessage = $LocalizedData.$ErrorType - - if(!$errorMessage) - { - $errorMessage = ($LocalizedData.NoKeyFound -f $ErrorType) - - if(!$errorMessage) - { - $errorMessage = ("No Localization key found for key: {0}" -f $ErrorType) - } - } - - $errorMessage = ($errorMessage -f $FormatArgs) - - if( $InnerException ) - { - $errorMessage += " InnerException: $($InnerException.Message)" - } - - $callStack = Get-PSCallStack - - # Get Name of calling script - if($callStack[1] -and $callStack[1].ScriptName) - { - $scriptPath = $callStack[1].ScriptName - - $callingScriptName = $scriptPath.Split('\')[-1].Split('.')[0] - - $errorId = "$callingScriptName.$ErrorType" - } - else - { - $errorId = $ErrorType - } - - Write-Verbose -Message "$($USLocalizedData.$ErrorType -f $FormatArgs) | ErrorType: $errorId" - - $exception = New-Object System.Exception $errorMessage, $InnerException - $errorRecord = New-Object System.Management.Automation.ErrorRecord $exception, $errorId, $ErrorCategory, $TargetObject - - return $errorRecord -} - -<# - .SYNOPSIS - Displays a localized warning message. - - .PARAMETER WarningType - String containing the key of the localized warning message. - - .PARAMETER FormatArgs - Collection of strings to replace format objects in warning message. -#> -function New-WarningMessage -{ - [CmdletBinding()] - param - ( - [Parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [String] - $WarningType, - - [String[]] - $FormatArgs - ) - - ## Attempt to get the string from the localized data - $warningMessage = $LocalizedData.$WarningType - - ## Ensure there is a message present in the localization file - if (!$warningMessage) - { - $errorParams = @{ - ErrorType = 'NoKeyFound' - FormatArgs = $WarningType - ErrorCategory = 'InvalidArgument' - TargetObject = 'New-WarningMessage' - } - - ## Raise an error indicating the localization data is not present - throw New-TerminatingError @errorParams - } - - ## Apply formatting - $warningMessage = $warningMessage -f $FormatArgs - - ## Write the message as a warning - Write-Warning -Message $warningMessage -} - -<# - .SYNOPSIS - Displays a standardized verbose message. - - .PARAMETER Message - String containing the key of the localized warning message. -#> -function New-VerboseMessage -{ - [CmdletBinding()] - [Alias()] - [OutputType([String])] - Param - ( - [Parameter(Mandatory=$true)] - $Message - ) - Write-Verbose -Message ((Get-Date -format yyyy-MM-dd_HH-mm-ss) + ": $Message") -Verbose -} - -<# - .SYNOPSIS - This method is used to compare current and desired values for any DSC resource. - - .PARAMETER CurrentValues - This is hashtable of the current values that are applied to the resource. - - .PARAMETER DesiredValues - This is a PSBoundParametersDictionary of the desired values for the resource. - - .PARAMETER ValuesToCheck - This is a list of which properties in the desired values list should be checked. - If this is empty then all values in DesiredValues are checked. -#> -function Test-SQLDscParameterState -{ - [CmdletBinding()] - param - ( - [Parameter(Mandatory = $true)] - [HashTable] - $CurrentValues, - - [Parameter(Mandatory = $true)] - [Object] - $DesiredValues, - - [Parameter()] - [Array] - $ValuesToCheck - ) - - $returnValue = $true - - if (($DesiredValues.GetType().Name -ne "HashTable") ` - -and ($DesiredValues.GetType().Name -ne "CimInstance") ` - -and ($DesiredValues.GetType().Name -ne "PSBoundParametersDictionary")) - { - throw "Property 'DesiredValues' in Test-SQLDscParameterState must be either a " + ` - "Hashtable or CimInstance. Type detected was $($DesiredValues.GetType().Name)" - } - - if (($DesiredValues.GetType().Name -eq "CimInstance") -and ($null -eq $ValuesToCheck)) - { - throw "If 'DesiredValues' is a CimInstance then property 'ValuesToCheck' must contain a value" - } - - if (($null -eq $ValuesToCheck) -or ($ValuesToCheck.Count -lt 1)) - { - $keyList = $DesiredValues.Keys - } - else - { - $keyList = $ValuesToCheck - } - - $keyList | ForEach-Object -Process { - if (($_ -ne "Verbose")) - { - if (($CurrentValues.ContainsKey($_) -eq $false) ` - -or ($CurrentValues.$_ -ne $DesiredValues.$_) ` - -or (($DesiredValues.ContainsKey($_) -eq $true) -and ($DesiredValues.$_.GetType().IsArray))) - { - if ($DesiredValues.GetType().Name -eq "HashTable" -or ` - $DesiredValues.GetType().Name -eq "PSBoundParametersDictionary") - { - - $checkDesiredValue = $DesiredValues.ContainsKey($_) - } - else - { - $checkDesiredValue = Test-SPDSCObjectHasProperty $DesiredValues $_ - } - - if ($checkDesiredValue) - { - $desiredType = $DesiredValues.$_.GetType() - $fieldName = $_ - if ($desiredType.IsArray -eq $true) - { - if (($CurrentValues.ContainsKey($fieldName) -eq $false) ` - -or ($null -eq $CurrentValues.$fieldName)) - { - New-VerboseMessage -Message ("Expected to find an array value for " + ` - "property $fieldName in the current " + ` - "values, but it was either not present or " + ` - "was null. This has caused the test method " + ` - "to return false.") - - $returnValue = $false - } - else - { - $arrayCompare = Compare-Object -ReferenceObject $CurrentValues.$fieldName ` - -DifferenceObject $DesiredValues.$fieldName - if ($null -ne $arrayCompare) - { - New-VerboseMessage -Message ("Found an array for property $fieldName " + ` - "in the current values, but this array " + ` - "does not match the desired state. " + ` - "Details of the changes are below.") - $arrayCompare | ForEach-Object -Process { - New-VerboseMessage -Message "$($_.InputObject) - $($_.SideIndicator)" - } - - $returnValue = $false - } - } - } - else - { - switch ($desiredType.Name) - { - "String" { - if (-not [String]::IsNullOrEmpty($CurrentValues.$fieldName) -or ` - -not [String]::IsNullOrEmpty($DesiredValues.$fieldName)) - { - New-VerboseMessage -Message ("String value for property $fieldName does not match. " + ` - "Current state is '$($CurrentValues.$fieldName)' " + ` - "and Desired state is '$($DesiredValues.$fieldName)'") - - $returnValue = $false - } - } - "Int32" { - if (-not ($DesiredValues.$fieldName -eq 0) -or ` - -not ($null -eq $CurrentValues.$fieldName)) - { - New-VerboseMessage -Message ("Int32 value for property " + "$fieldName does not match. " + ` - "Current state is " + "'$($CurrentValues.$fieldName)' " + ` - "and desired state is " + "'$($DesiredValues.$fieldName)'") - - $returnValue = $false - } - } - "Int16" { - if (-not ($DesiredValues.$fieldName -eq 0) -or ` - -not ($null -eq $CurrentValues.$fieldName)) - { - New-VerboseMessage -Message ("Int32 value for property " + "$fieldName does not match. " + ` - "Current state is " + "'$($CurrentValues.$fieldName)' " + ` - "and desired state is " + "'$($DesiredValues.$fieldName)'") - - $returnValue = $false - } - } - default { - New-VerboseMessage -Message ("Unable to compare property $fieldName " + ` - "as the type ($($desiredType.Name)) is " + ` - "not handled by the Test-SQLDscParameterState cmdlet") - - $returnValue = $false - } - } - } - } - } - } - } - - return $returnValue -} - -<# - .SYNOPSIS - Connect to a SQL Server Database Engine and give the server permissions 'AlterAnyAvailabilityGroup' and 'ViewServerState' to the provided user. - - .PARAMETER SQLServer - String containing the host name of the SQL Server to connect to. - - .PARAMETER SQLInstanceName - String containing the SQL Server Database Engine instance to connect to. - - .PARAMETER SetupCredential - PSCredential object with the credentials to use to impersonate a user when connecting. - If this is not provided then the current user will be used to connect to the SQL Server Database Engine instance. - - .PARAMETER AuthorizedUser - String containing the user to give the server permissions 'AlterAnyAvailabilityGroup' and 'ViewServerState'. -#> -function Grant-ServerPerms -{ - [CmdletBinding()] - param - ( - [ValidateNotNull()] - [System.String] - $SQLServer = $env:COMPUTERNAME, - - [ValidateNotNull()] - [System.String] - $SQLInstanceName= "MSSQLSERVER", - - [ValidateNotNullOrEmpty()] - [Parameter(Mandatory = $true)] - [System.Management.Automation.PSCredential] - $SetupCredential, - - [ValidateNotNullOrEmpty()] - [Parameter(Mandatory = $true)] - [System.String] - $AuthorizedUser - ) - - if(!$SQL) - { - $SQL = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName -SetupCredential $SetupCredential - } - Try{ - $sps = New-Object Microsoft.SqlServer.Management.Smo.ServerPermissionSet([Microsoft.SqlServer.Management.Smo.ServerPermission]::AlterAnyAvailabilityGroup) - $sps.Add([Microsoft.SqlServer.Management.Smo.ServerPermission]::ViewServerState) - $SQL.Grant($sps,$AuthorizedUser) - New-VerboseMessage -Message "Granted Permissions to $AuthorizedUser" - } - Catch{ - Write-Error "Failed to grant Permissions to $AuthorizedUser." - } -} - -<# - .SYNOPSIS - Connect to a Active Directory and give the Cluster Name Object all rights on the cluster Virtual Computer Object (VCO). - - .PARAMETER AvailabilityGroupNameListener - String containing the name of the Availabilty Group's Virtual Computer Object (VCO). - - .PARAMETER CNO - String containing the name of the Cluster Name Object (CNO) for the failover cluster. -#> -function Grant-CNOPerms -{ -[CmdletBinding()] - Param - ( - [ValidateNotNullOrEmpty()] - [Parameter(Mandatory = $true)] - [System.String] - $AvailabilityGroupNameListener, - - [ValidateNotNullOrEmpty()] - [Parameter(Mandatory = $true)] - [System.String] - $CNO - ) - - #Verify Active Directory Tools are installed, if they are load if not Throw Error - If (!(Get-Module -ListAvailable | Where-Object {$_.Name -eq "ActiveDirectory"})){ - Throw "Active Directory Module is not installed and is Required." - Exit - } - else{Import-Module ActiveDirectory -ErrorAction Stop -Verbose:$false} - Try{ - $AG = Get-ADComputer $AvailabilityGroupNameListener - - $comp = $AG.DistinguishedName # input AD computer distinguishedname - $acl = Get-Acl "AD:\$comp" - $u = Get-ADComputer $CNO # get the AD user object given full control to computer - $SID = [System.Security.Principal.SecurityIdentifier] $u.SID - - $identity = [System.Security.Principal.IdentityReference] $SID - $adRights = [System.DirectoryServices.ActiveDirectoryRights] "GenericAll" - $type = [System.Security.AccessControl.AccessControlType] "Allow" - $inheritanceType = [System.DirectoryServices.ActiveDirectorySecurityInheritance] "All" - $ace = New-Object System.DirectoryServices.ActiveDirectoryAccessRule $identity,$adRights,$type,$inheritanceType - - $acl.AddAccessRule($ace) - Set-Acl -AclObject $acl "AD:\$comp" - New-VerboseMessage -Message "Granted privileges on $comp to $CNO" - } - Catch{ - Throw "Failed to grant Permissions on $comp." - Exit - } -} - -<# - .SYNOPSIS - Create a new computer object for a Availabilty Group's Virtual Computer Object (VCO). - - .PARAMETER AvailabilityGroupNameListener - String containing the name of the Availabilty Group's Virtual Computer Object (VCO). - - .PARAMETER SQLServer - String containing the host name of the SQL Server to connect to. - - .PARAMETER SQLInstanceName - String containing the SQL Server Database Engine instance to connect to. - - .PARAMETER SetupCredential - PSCredential object with the credentials to use to impersonate a user when connecting. - If this is not provided then the current user will be used to connect to the SQL Server Database Engine instance. -#> -function New-ListenerADObject -{ -[CmdletBinding()] - Param - ( - [ValidateNotNullOrEmpty()] - [Parameter(Mandatory = $true)] - [System.String] - $AvailabilityGroupNameListener, - - [ValidateNotNull()] - [System.String] - $SQLServer = $env:COMPUTERNAME, - - [ValidateNotNull()] - [System.String] - $SQLInstanceName = "MSSQLSERVER", - - [ValidateNotNullOrEmpty()] - [Parameter(Mandatory = $true)] - [System.Management.Automation.PSCredential] - $SetupCredential - ) - - if(!$SQL) - { - $SQL = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName -SetupCredential $SetupCredential - } - - $CNO= $SQL.ClusterName - - #Verify Active Directory Tools are installed, if they are load if not Throw Error - If (!(Get-Module -ListAvailable | Where-Object {$_.Name -eq "ActiveDirectory"})){ - Throw "Active Directory Module is not installed and is Required." - Exit - } - else{Import-Module ActiveDirectory -ErrorAction Stop -Verbose:$false} - try{ - $CNO_OU = Get-ADComputer $CNO - #Accounts for the comma and CN= at the start of Distinguished Name - #We want to remove these plus the ClusterName to get the actual OU Path. - $AdditionalChars = 4 - $Trim = $CNO.Length+$AdditionalChars - $CNOlgth = $CNO_OU.DistinguishedName.Length - $trim - $OUPath = $CNO_OU.ToString().Substring($Trim,$CNOlgth) - } - catch{ - Throw ": Failed to find Computer in AD" - exit - } - - - $m = Get-ADComputer -Filter {Name -eq $AvailabilityGroupNameListener} -Server $env:USERDOMAIN | Select-Object -Property * | Measure-Object - - If ($m.Count -eq 0) - { - Try{ - #Create Computer Object for the AgListenerName - New-ADComputer -Name $AvailabilityGroupNameListener -SamAccountName $AvailabilityGroupNameListener -Path $OUPath -Enabled $false -Credential $SetupCredential - New-VerboseMessage -Message "Created Computer Object $AvailabilityGroupNameListener" - } - Catch{ - Throw "Failed to Create $AvailabilityGroupNameListener in $OUPath" - Exit - } - - $SuccessChk =0 - - #Check for AD Object Validate at least three successful attempts - $i=1 - While ($i -le 5) { - Try{ - $ListChk = Get-ADComputer -filter {Name -like $AvailabilityGroupNameListener} - If ($ListChk){$SuccessChk++} - Start-Sleep -Seconds 10 - If($SuccesChk -eq 3){break} - } - Catch{ - Throw "Failed Validate $AvailabilityGroupNameListener was created in $OUPath" - Exit - } - $i++ - } - } - Try{ - Grant-CNOPerms -AvailabilityGroupNameListener $AvailabilityGroupNameListener -CNO $CNO - } - Catch{ - Throw "Failed Validate grant permissions on $AvailabilityGroupNameListener in location $OUPAth to $CNO" - Exit - } - -} - -<# - .SYNOPSIS - Imports the module SQLPS in a standardized way. -#> -function Import-SQLPSModule -{ - [CmdletBinding()] - param() - - $module = (Get-Module -FullyQualifiedName 'SqlServer' -ListAvailable).Name - if ($module) - { - New-VerboseMessage -Message 'Preferred module SqlServer found.' - } - else - { - New-VerboseMessage -Message 'Module SqlServer not found, trying to use older SQLPS module.' - $module = (Get-Module -FullyQualifiedName 'SQLPS' -ListAvailable).Name - } - - if ($module) - { - try - { - Write-Debug -Message 'SQLPS module changes CWD to SQLSERVER:\ when loading, pushing location to pop it when module is loaded.' - Push-Location - - New-VerboseMessage -Message ('Importing {0} module.' -f $module) - - <# - SQLPS has unapproved verbs, disable checking to ignore Warnings. - Suppressing verbose so all cmdlet is not llsted. - #> - Import-Module -Name $module -DisableNameChecking -Verbose:$False -ErrorAction Stop - - Write-Debug -Message ('Module {0} imported.' -f $module) - } - catch - { - throw New-TerminatingError -ErrorType FailedToImportSqlModule -FormatArgs @($module) -ErrorCategory InvalidOperation -InnerException $_.Exception - } - finally - { - Write-Debug -Message 'Popping location back to what it was before importing SQLPS module.' - Pop-Location - } - } - else - { - throw New-TerminatingError -ErrorType SqlModuleNotFound -ErrorCategory InvalidOperation -InnerException $_.Exception - } -} - -<# - .SYNOPSIS - Returns the SQL Server instance name in the way SQLPS Provider expect it. - - .DESCRIPTION - The SQLPS Provider doesn't use the default instance name of MSSQLSERVER, instead it uses DEFAULT. - This function make sure the correct default instance name is returned. - - .PARAMETER InstanceName - String containing the SQL Server Database Engine instance to validate. -#> -function Get-SQLPSInstanceName -{ - [CmdletBinding()] - [OutputType([String])] - param - ( - [Parameter(Mandatory = $true)] - [System.String] - $InstanceName - ) - - if( $InstanceName -eq "MSSQLSERVER" ) { - $InstanceName = "DEFAULT" - } - - return $InstanceName -} - -<# - .SYNOPSIS - Returns the SQL Server SQLPS provider server object. - - .PARAMETER InstanceName - String containing the SQL Server Database Engine instance to connect to. - - .PARAMETER NodeName - String containing the host name of the SQL Server to connect to. -#> -function Get-SQLPSInstance -{ - [CmdletBinding()] - [OutputType([String])] - param - ( - [Parameter(Mandatory = $true)] - [System.String] - $InstanceName, - - [Parameter(Mandatory = $true)] - [System.String] - $NodeName - ) - - $InstanceName = Get-SQLPSInstanceName -InstanceName $InstanceName - $Path = "SQLSERVER:\SQL\$NodeName\$InstanceName" - - New-VerboseMessage -Message "Connecting to $Path as $([System.Security.Principal.WindowsIdentity]::GetCurrent().Name)" - - Import-SQLPSModule - $instance = Get-Item $Path - - return $instance -} - -<# - .SYNOPSIS - Restarts a SQL Server instance and associated services - - .PARAMETER SQLServer - Hostname of the SQL Server to be configured - - .PARAMETER SQLInstanceName - Name of the SQL instance to be configued. Default is 'MSSQLSERVER' - - .PARAMETER Timeout - Timeout value for restarting the SQL services. The default value is 120 seconds. - - .EXAMPLE - Restart-SqlService -SQLServer localhost - - .EXAMPLE - Restart-SqlService -SQLServer localhost -SQLInstanceName 'NamedInstance' - - .EXAMPLE - Restart-SqlService -SQLServer CLU01 -Timeout 300 -#> -function Restart-SqlService -{ - [CmdletBinding()] - param - ( - [Parameter(Mandatory = $true)] - [String] - $SQLServer, - - [Parameter()] - [String] - $SQLInstanceName = 'MSSQLSERVER', - - [Parameter()] - [Int32] - $Timeout = 120 - ) - - ## Connect to the instance - $serverObject = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName - - if ($serverObject.IsClustered) - { - ## Get the cluster resources - New-VerboseMessage -Message 'Getting cluster resource for SQL Server' - $sqlService = Get-CimInstance -Namespace root/MSCluster -ClassName MSCluster_Resource -Filter "Type = 'SQL Server'" | - Where-Object { $_.PrivateProperties.InstanceName -eq $serverObject.ServiceName } - - New-VerboseMessage -Message 'Getting active cluster resource SQL Server Agent' - $agentService = $sqlService | Get-CimAssociatedInstance -ResultClassName MSCluster_Resource | - Where-Object { ($_.Type -eq "SQL Server Agent") -and ($_.State -eq 2) } - - ## Build a listing of resources being acted upon - $resourceNames = @($sqlService.Name, ($agentService | Select-Object -ExpandProperty Name)) -join "," - - ## Stop the SQL Server and dependent resources - New-VerboseMessage -Message "Bringing the SQL Server resources $resourceNames offline." - $sqlService | Invoke-CimMethod -MethodName TakeOffline -Arguments @{ Timeout = $Timeout } - - ## Start the SQL server resource - New-VerboseMessage -Message 'Bringing the SQL Server resource back online.' - $sqlService | Invoke-CimMethod -MethodName BringOnline -Arguments @{ Timeout = $Timeout } - - ## Start the SQL Agent resource - if ($agentService) - { - New-VerboseMessage -Message 'Bringing the SQL Server Agent resource online.' - $agentService | Invoke-CimMethod -MethodName BringOnline -Arguments @{ Timeout = $Timeout } - } - } - else - { - New-VerboseMessage -Message 'Getting SQL Service information' - $sqlService = Get-Service -DisplayName "SQL Server ($($serverObject.ServiceName))" - - ## Get all dependent services that are running. - ## There are scenarios where an automatic service is stopped and should not be restarted automatically. - $agentService = $sqlService.DependentServices | Where-Object { $_.Status -eq "Running" } - - ## Restart the SQL Server service - New-VerboseMessage -Message 'SQL Server service restarting' - $sqlService | Restart-Service -Force - - ## Start dependent services - $agentService | ForEach-Object { - New-VerboseMessage -Message "Starting $($_.DisplayName)" - $_ | Start-Service - } - } -} - -<# - .SYNOPSIS - This cmdlet is used to return the permission for a user in a database - - .PARAMETER SqlServerObject - This is the Server object returned by Connect-SQL - - .PARAMETER Name - This is the name of the user to get the current permissions for - - .PARAMETER Database - This is the name of the SQL database - - .PARAMETER PermissionState - If the permission should be granted or denied. Valid values are Grant or Deny -#> -function Get-SqlDatabasePermission -{ - [CmdletBinding()] - param - ( - [Parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [System.Object] - $SqlServerObject, - - [Parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [System.String] - $Name, - - [Parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [System.String] - $Database, - - [Parameter(Mandatory = $true)] - [ValidateSet('Grant','Deny')] - [ValidateNotNullOrEmpty()] - [System.String] - $PermissionState - ) - - Write-Verbose -Message 'Evaluating database and login.' - $sqlDatabase = $SqlServerObject.Databases[$Database] - $sqlLogin = $SqlServerObject.Logins[$Name] - $sqlInstanceName = $SqlServerObject.InstanceName - $sqlServer = $SqlServerObject.ComputerNamePhysicalNetBIOS - - # Initialize variable permission - [System.String[]] $permission = @() - - if ($sqlDatabase) - { - if ($sqlLogin) - { - Write-Verbose -Message "Getting permissions for user '$Name' in database '$Database'." - - $databasePermissionInfo = $sqlDatabase.EnumDatabasePermissions($Name) - $databasePermissionInfo = $databasePermissionInfo | Where-Object -FilterScript { - $_.PermissionState -eq $PermissionState - } - - foreach ($currentDatabasePermissionInfo in $databasePermissionInfo) - { - $permissionProperty = ($currentDatabasePermissionInfo.PermissionType | Get-Member -MemberType Property).Name - foreach ($currentPermissionProperty in $permissionProperty) - { - if ($currentDatabasePermissionInfo.PermissionType."$currentPermissionProperty") - { - $permission += $currentPermissionProperty - } - } - } - } - else - { - throw New-TerminatingError -ErrorType LoginNotFound ` - -FormatArgs @($Name,$sqlServer,$sqlInstanceName) ` - -ErrorCategory ObjectNotFound - } - } - else - { - throw New-TerminatingError -ErrorType NoDatabase ` - -FormatArgs @($Database,$sqlServer,$sqlInstanceName) ` - -ErrorCategory InvalidResult - } - - $permission -} - -<# - .SYNOPSIS - This cmdlet is used to grant or deny permissions for a user in a database - - .PARAMETER SqlServerObject - This is the Server object returned by Connect-SQL - - .PARAMETER Name - This is the name of the user to get the current permissions for - - .PARAMETER Database - This is the name of the SQL database - - .PARAMETER PermissionState - If the permission should be granted or denied. Valid values are Grant or Deny - - .PARAMETER Permissions - The permissions to be granted or denied for the user in the database. - Valid permissions can be found in the article SQL Server Permissions: - https://msdn.microsoft.com/en-us/library/ms191291.aspx#SQL Server Permissions -#> -function Add-SqlDatabasePermission -{ - [CmdletBinding()] - param - ( - [Parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [System.Object] - $SqlServerObject, - - [Parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [System.String] - $Name, - - [Parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [System.String] - $Database, - - [Parameter(Mandatory = $true)] - [ValidateSet('Grant','Deny')] - [ValidateNotNullOrEmpty()] - [System.String] - $PermissionState, - - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [System.String[]] - $Permissions - ) - - Write-Verbose -Message 'Evaluating database and login.' - $sqlDatabase = $SqlServerObject.Databases[$Database] - $sqlLogin = $SqlServerObject.Logins[$Name] - $sqlInstanceName = $SqlServerObject.InstanceName - $sqlServer = $SqlServerObject.ComputerNamePhysicalNetBIOS - - if ($sqlDatabase) - { - if ($sqlLogin) - { - if (!$sqlDatabase.Users[$Name]) - { - try - { - Write-Verbose -Message ("Adding SQL login $Name as a user of database " + ` - "$Database on $sqlServer\$sqlInstanceName") - $sqlDatabaseUser = New-Object Microsoft.SqlServer.Management.Smo.User $sqlDatabase,$Name - $sqlDatabaseUser.Login = $Name - $sqlDatabaseUser.Create() - } - catch - { - Write-Verbose -Message ("Failed adding SQL login $Name as a user of " + ` - "database $Database on $sqlServer\$sqlInstanceName") - } - } - - if ($sqlDatabase.Users[$Name]) - { - try - { - Write-Verbose -Message ("$PermissionState the permissions '$Permissions' to the " + ` - "database '$Database' on the server $sqlServer$sqlInstanceName") - $permissionSet = New-Object -TypeName Microsoft.SqlServer.Management.Smo.DatabasePermissionSet - - foreach ($permission in $permissions) - { - $permissionSet."$permission" = $true - } - - switch ($PermissionState) - { - 'Grant' - { - $sqlDatabase.Grant($permissionSet,$Name) - } - - 'Deny' - { - $sqlDatabase.Deny($permissionSet,$Name) - } - } - } - catch - { - Write-Verbose -Message ("Failed setting SQL login $Name to permissions $permissions " + ` - "on database $Database on $sqlServer\$sqlInstanceName") - } - } - } - else - { - throw New-TerminatingError -ErrorType LoginNotFound ` - -FormatArgs @($Name,$sqlServer,$sqlInstanceName) ` - -ErrorCategory ObjectNotFound - } - } - else - { - throw New-TerminatingError -ErrorType NoDatabase ` - -FormatArgs @($Database,$sqlServer,$sqlInstanceName) ` - -ErrorCategory InvalidResult - } -} - -<# - .SYNOPSIS - This cmdlet is used to remove (revoke) permissions for a user in a database - - .PARAMETER SqlServerObject - This is the Server object returned by Connect-SQL. - - .PARAMETER Name - This is the name of the user for which permissions will be removed (revoked) - - .PARAMETER Database - This is the name of the SQL database - - .PARAMETER PermissionState - f the permission that should be removed was granted or denied. Valid values are Grant or Deny - - .PARAMETER Permissions - The permissions to be remove (revoked) for the user in the database. - Valid permissions can be found in the article SQL Server Permissions: - https://msdn.microsoft.com/en-us/library/ms191291.aspx#SQL Server Permissions. -#> -function Remove-SqlDatabasePermission -{ - [CmdletBinding()] - param - ( - [Parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [System.Object] - $SqlServerObject, - - [Parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [System.String] - $Name, - - [Parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [System.String] - $Database, - - [Parameter(Mandatory = $true)] - [ValidateSet('Grant','Deny')] - [ValidateNotNullOrEmpty()] - [System.String] - $PermissionState, - - [parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [System.String[]] - $Permissions - ) - - Write-Verbose -Message 'Evaluating database and login' - $sqlDatabase = $SqlServerObject.Databases[$Database] - $sqlLogin = $SqlServerObject.Logins[$Name] - $sqlInstanceName = $SqlServerObject.InstanceName - $sqlServer = $SqlServerObject.ComputerNamePhysicalNetBIOS - - if ($sqlDatabase) - { - if ($sqlLogin) - { - if (!$sqlDatabase.Users[$Name]) - { - try - { - Write-Verbose -Message ("Adding SQL login $Name as a user of database " + ` - "$Database on $sqlServer\$sqlInstanceName") - $sqlDatabaseUser = New-Object -TypeName Microsoft.SqlServer.Management.Smo.User ` - -ArgumentList $sqlDatabase,$Name - $sqlDatabaseUser.Login = $Name - $sqlDatabaseUser.Create() - } - catch - { - Write-Verbose -Message ("Failed adding SQL login $Name as a user of " + ` - "database $Database on $sqlServer\$sqlInstanceName") - } - } - - if ($sqlDatabase.Users[$Name]) - { - try - { - Write-Verbose -Message ("Revoking $PermissionState permissions '$Permissions' to the " + ` - "database '$Database' on the server $sqlServer$sqlInstanceName") - $permissionSet = New-Object -TypeName Microsoft.SqlServer.Management.Smo.DatabasePermissionSet - - foreach ($permission in $permissions) - { - $permissionSet."$permission" = $false - } - - switch ($PermissionState) - { - 'Grant' - { - $sqlDatabase.Grant($permissionSet,$Name) - } - - 'Deny' - { - $sqlDatabase.Deny($permissionSet,$Name) - } - } - } - catch - { - Write-Verbose -Message ("Failed removing SQL login $Name to permissions $permissions " + ` - "on database $Database on $sqlServer\$sqlInstanceName") - } - } - } - else - { - throw New-TerminatingError -ErrorType LoginNotFound ` - -FormatArgs @($Name,$sqlServer,$sqlInstanceName) ` - -ErrorCategory ObjectNotFound - } - } - else - { - throw New-TerminatingError -ErrorType NoDatabase ` - -FormatArgs @($Database,$sqlServer,$sqlInstanceName) ` - -ErrorCategory InvalidResult - } -} - -<# - .SYNOPSIS - Executes a query on the specified database. - - .PARAMETER SQLServer - The hostname of the server that hosts the SQL instance. - - .PARAMETER SQLInstanceName - The name of the SQL instance that hosts the database. - - .PARAMETER Database - Specify the name of the database to execute the query on. - - .PARAMETER Query - The query string to execute. - - .PARAMETER WithResults - Specifies if the query should return results. - - .EXAMPLE - Invoke-Query -SQLServer Server1 -SQLInstanceName MSSQLSERVER -Database master -Query 'SELECT name FROM sys.databases' -WithResults - - .EXAMPLE - Invoke-Query -SQLServer Server1 -SQLInstanceName MSSQLSERVER -Database master -Query 'RESTORE DATABASE [NorthWinds] WITH RECOVERY' -#> -function Invoke-Query -{ - [CmdletBinding()] - param - ( - [Parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [String] - $SQLServer, - - [Parameter(Mandatory = $true)] - [String] - $SQLInstanceName, - - [Parameter(Mandatory = $true)] - [String] - $Database, - - [Parameter(Mandatory = $true)] - [String] - $Query, - - [Parameter()] - [Switch] - $WithResults - ) - - $serverObject = Connect-SQL -SQLServer $SQLServer -SQLInstanceName $SQLInstanceName - - if ( $WithResults ) - { - try - { - $result = $serverObject.Databases[$Database].ExecuteWithResults($Query) - } - catch - { - throw New-TerminatingError -ErrorType ExecuteQueryWithResultsFailed -FormatArgs $Database -ErrorCategory NotSpecified - } - } - else - { - try - { - $serverObject.Databases[$Database].ExecuteNonQuery($Query) - } - catch - { - throw New-TerminatingError -ErrorType ExecuteNonQueryFailed -FormatArgs $Database -ErrorCategory NotSpecified - } - } - - return $result -} - -<# - .SYNOPSIS - Executes the alter method on an Availability Group Replica object. - - .PARAMETER AvailabilityGroupReplica - The Availabilty Group Replica object that must be altered. -#> -function Update-AvailabilityGroupReplica -{ - param - ( - [Parameter(Mandatory = $true)] - [Microsoft.SqlServer.Management.Smo.AvailabilityReplica] - $AvailabilityGroupReplica - ) - - try - { - $originalErrorActionPreference = $ErrorActionPreference - $ErrorActionPreference = 'Stop' - $AvailabilityGroupReplica.Alter() - } - catch - { - throw New-TerminatingError -ErrorType AlterAvailabilityGroupReplicaFailed -FormatArgs $AvailabilityGroupReplica.Name -ErrorCategory OperationStopped - } - finally - { - $ErrorActionPreference = $originalErrorActionPreference - } -} - -function Test-LoginEffectivePermissions -{ - param - ( - [Parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [String] - $SQLServer, - - [Parameter(Mandatory = $true)] - [String] - $SQLInstanceName, - - [Parameter(Mandatory = $true)] - [ValidateNotNullOrEmpty()] - [string] - $LoginName, - - [Parameter(Mandatory = $true)] - [string[]] - $Permissions - ) - - # Assume the permissions are not present - $permissionsPresent = $false - - $invokeQueryParams = @{ - SQLServer = $SQLServer - SQLInstanceName = $SQLInstanceName - Database = 'master' - WithResults = $true - } - - $queryToGetEffectivePermissionsForLogin = " - EXECUTE AS LOGIN = '$LoginName' - SELECT DISTINCT permission_name - FROM fn_my_permissions(null,'SERVER') - REVERT - " - - New-VerboseMessage -Message "Getting the effective permissions for the login '$LoginName' on '$sqlInstanceName'." - - $loginEffectivePermissionsResult = Invoke-Query @invokeQueryParams -Query $queryToGetEffectivePermissionsForLogin - $loginEffectivePermissions = $loginEffectivePermissionsResult.Tables.Rows.permission_name - - if ( $null -ne $loginEffectivePermissions ) - { - $loginMissingPermissions = Compare-Object -ReferenceObject $Permissions -DifferenceObject $loginEffectivePermissions | - Where-Object -FilterScript { $_.SideIndicator -ne '=>' } | - Select-Object -ExpandProperty InputObject - - if ( $loginMissingPermissions.Count -eq 0 ) - { - $permissionsPresent = $true - } - } - - return $permissionsPresent -} From 7a13ce8379d492191ea639b42e4cc5fe3af47f01 Mon Sep 17 00:00:00 2001 From: James Pogran Date: Fri, 9 Feb 2018 20:14:39 -0500 Subject: [PATCH 06/25] (MODULES-6592) Update OfficeOnlineServerDsc to 1.2.0.0 This commit updates OfficeOnlineServerDSc to the latest gallery version --- dsc_resource_release_tags.yml | 2 +- lib/puppet/type/dsc_officeonlineserverfarm.rb | 2 +- .../type/dsc_officeonlineserverinstall.rb | 2 +- ...c_officeonlineserverinstalllanguagepack.rb | 122 +++++++++++++ .../type/dsc_officeonlineservermachine.rb | 2 +- .../MSFT_OfficeOnlineServerFarm.psm1 | 153 +++++++++++++++- ...OfficeOnlineServerInstallLanguagePack.psm1 | 167 ++++++++++++++++++ ...OnlineServerInstallLanguagePack.schema.mof | 8 + .../MSFT_OfficeOnlineServerMachine.psm1 | 13 +- .../OfficeOnlineServerDsc.psd1 | 17 +- types.md | 1 + 11 files changed, 469 insertions(+), 20 deletions(-) create mode 100644 lib/puppet/type/dsc_officeonlineserverinstalllanguagepack.rb create mode 100644 lib/puppet_x/dsc_resources/OfficeOnlineServerDsc/DSCResources/MSFT_OfficeOnlineServerInstallLanguagePack/MSFT_OfficeOnlineServerInstallLanguagePack.psm1 create mode 100644 lib/puppet_x/dsc_resources/OfficeOnlineServerDsc/DSCResources/MSFT_OfficeOnlineServerInstallLanguagePack/MSFT_OfficeOnlineServerInstallLanguagePack.schema.mof diff --git a/dsc_resource_release_tags.yml b/dsc_resource_release_tags.yml index 033fffbc8..11558ec5f 100644 --- a/dsc_resource_release_tags.yml +++ b/dsc_resource_release_tags.yml @@ -1,6 +1,6 @@ --- AuditPolicyDsc: 1.1.0.0-PSGallery -OfficeOnlineServerDsc: 1.0.0.0-PSGallery +OfficeOnlineServerDsc: 1.2.0.0-PSGallery SecurityPolicyDsc: 1.5.0.0-PSGallery SharePointDsc: 1.8.0.0-PSGallery SqlServerDsc: 11.0.0.0-PSGallery diff --git a/lib/puppet/type/dsc_officeonlineserverfarm.rb b/lib/puppet/type/dsc_officeonlineserverfarm.rb index 851c80c71..0c853777f 100644 --- a/lib/puppet/type/dsc_officeonlineserverfarm.rb +++ b/lib/puppet/type/dsc_officeonlineserverfarm.rb @@ -27,7 +27,7 @@ def dscmeta_resource_friendly_name; 'OfficeOnlineServerFarm' end def dscmeta_resource_name; 'MSFT_OfficeOnlineServerFarm' end def dscmeta_module_name; 'OfficeOnlineServerDsc' end - def dscmeta_module_version; '1.0.0.0' end + def dscmeta_module_version; '1.2.0.0' end newparam(:name, :namevar => true ) do end diff --git a/lib/puppet/type/dsc_officeonlineserverinstall.rb b/lib/puppet/type/dsc_officeonlineserverinstall.rb index 763a9b9fd..347975ae8 100644 --- a/lib/puppet/type/dsc_officeonlineserverinstall.rb +++ b/lib/puppet/type/dsc_officeonlineserverinstall.rb @@ -27,7 +27,7 @@ def dscmeta_resource_friendly_name; 'OfficeOnlineServerInstall' end def dscmeta_resource_name; 'MSFT_OfficeOnlineServerInstall' end def dscmeta_module_name; 'OfficeOnlineServerDsc' end - def dscmeta_module_version; '1.0.0.0' end + def dscmeta_module_version; '1.2.0.0' end newparam(:name, :namevar => true ) do end diff --git a/lib/puppet/type/dsc_officeonlineserverinstalllanguagepack.rb b/lib/puppet/type/dsc_officeonlineserverinstalllanguagepack.rb new file mode 100644 index 000000000..dd08dd513 --- /dev/null +++ b/lib/puppet/type/dsc_officeonlineserverinstalllanguagepack.rb @@ -0,0 +1,122 @@ +require 'pathname' + +Puppet::Type.newtype(:dsc_officeonlineserverinstalllanguagepack) do + require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' + require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' + + + @doc = %q{ + The DSC OfficeOnlineServerInstallLanguagePack resource type. + Automatically generated from + 'OfficeOnlineServerDsc/DSCResources/MSFT_OfficeOnlineServerInstallLanguagePack/MSFT_OfficeOnlineServerInstallLanguagePack.schema.mof' + + To learn more about PowerShell Desired State Configuration, please + visit https://technet.microsoft.com/en-us/library/dn249912.aspx. + + For more information about built-in DSC Resources, please visit + https://technet.microsoft.com/en-us/library/dn249921.aspx. + + For more information about xDsc Resources, please visit + https://github.com/PowerShell/DscResources. + } + + validate do + fail('dsc_ensure is a required attribute') if self[:dsc_ensure].nil? + fail('dsc_binarydir is a required attribute') if self[:dsc_binarydir].nil? + end + + def dscmeta_resource_friendly_name; 'OfficeOnlineServerInstallLanguagePack' end + def dscmeta_resource_name; 'MSFT_OfficeOnlineServerInstallLanguagePack' end + def dscmeta_module_name; 'OfficeOnlineServerDsc' end + def dscmeta_module_version; '1.2.0.0' end + + newparam(:name, :namevar => true ) do + end + + ensurable do + newvalue(:exists?) { provider.exists? } + newvalue(:present) { provider.create } + newvalue(:absent) { provider.destroy } + defaultto { :present } + end + + # Name: PsDscRunAsCredential + # Type: MSFT_Credential + # IsMandatory: False + # Values: None + newparam(:dsc_psdscrunascredential) do + def mof_type; 'MSFT_Credential' end + def mof_is_embedded?; true end + desc "PsDscRunAsCredential" + validate do |value| + unless value.kind_of?(Hash) + fail("Invalid value '#{value}'. Should be a hash") + end + PuppetX::Dsc::TypeHelpers.validate_MSFT_Credential("Credential", value) + end + end + + # Name: Ensure + # Type: string + # IsMandatory: True + # Values: ["Present", "Absent"] + newparam(:dsc_ensure) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Ensure - Set to 'present' to specificy that the product should be installed. Valid values are Present, Absent." + isrequired + validate do |value| + resource[:ensure] = value.downcase + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + unless ['Present', 'present', 'Absent', 'absent'].include?(value) + fail("Invalid value '#{value}'. Valid values are Present, Absent") + end + end + end + + # Name: BinaryDir + # Type: string + # IsMandatory: True + # Values: None + newparam(:dsc_binarydir) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "BinaryDir - Path to setup.exe" + isrequired + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Language + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_language) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Language - Language code for the package" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + + def builddepends + pending_relations = super() + PuppetX::Dsc::TypeHelpers.ensure_reboot_relationship(self, pending_relations) + end +end + +Puppet::Type.type(:dsc_officeonlineserverinstalllanguagepack).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do + confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) + defaultfor :operatingsystem => :windows + + mk_resource_methods +end diff --git a/lib/puppet/type/dsc_officeonlineservermachine.rb b/lib/puppet/type/dsc_officeonlineservermachine.rb index fdfea6d38..1a5dbefc0 100644 --- a/lib/puppet/type/dsc_officeonlineservermachine.rb +++ b/lib/puppet/type/dsc_officeonlineservermachine.rb @@ -27,7 +27,7 @@ def dscmeta_resource_friendly_name; 'OfficeOnlineServerMachine' end def dscmeta_resource_name; 'MSFT_OfficeOnlineServerMachine' end def dscmeta_module_name; 'OfficeOnlineServerDsc' end - def dscmeta_module_version; '1.0.0.0' end + def dscmeta_module_version; '1.2.0.0' end newparam(:name, :namevar => true ) do end diff --git a/lib/puppet_x/dsc_resources/OfficeOnlineServerDsc/DSCResources/MSFT_OfficeOnlineServerFarm/MSFT_OfficeOnlineServerFarm.psm1 b/lib/puppet_x/dsc_resources/OfficeOnlineServerDsc/DSCResources/MSFT_OfficeOnlineServerFarm/MSFT_OfficeOnlineServerFarm.psm1 index 1f5638df0..4f33c1107 100644 --- a/lib/puppet_x/dsc_resources/OfficeOnlineServerDsc/DSCResources/MSFT_OfficeOnlineServerFarm/MSFT_OfficeOnlineServerFarm.psm1 +++ b/lib/puppet_x/dsc_resources/OfficeOnlineServerDsc/DSCResources/MSFT_OfficeOnlineServerFarm/MSFT_OfficeOnlineServerFarm.psm1 @@ -14,154 +14,203 @@ function Get-TargetResource [OutputType([System.Collections.Hashtable])] param ( + [Parameter()] [System.Boolean] $AllowCEIP, + [Parameter()] [System.Boolean] $AllowHttp, + [Parameter()] [System.Boolean] $AllowHttpSecureStoreConnections, + [Parameter()] [System.String] $CacheLocation, + [Parameter()] [System.Int32] $CacheSizeInGB, + [Parameter()] [System.String] $CertificateName, + [Parameter()] [System.Boolean] $ClipartEnabled, + [Parameter()] [System.Int32] $DocumentInfoCacheSize, + [Parameter()] [System.Boolean] $EditingEnabled, + [Parameter()] [System.Boolean] $ExcelAllowExternalData, + [Parameter()] [System.Int32] $ExcelConnectionLifetime, + [Parameter()] [System.Int32] $ExcelExternalDataCacheLifetime, + [Parameter()] [System.Int32] $ExcelPrivateBytesMax, + [Parameter()] [System.Int32] $ExcelRequestDurationMax, + [Parameter()] [System.Int32] $ExcelSessionTimeout, + [Parameter()] [System.Boolean] $ExcelUdfsAllowed, + [Parameter()] [System.Boolean] $ExcelWarnOnDataRefresh, + [Parameter()] [System.Int32] $ExcelWorkbookSizeMax, + [Parameter()] [System.Int32] $ExcelMemoryCacheThreshold, + [Parameter()] [System.Int32] $ExcelUnusedObjectAgeMax, + [Parameter()] [System.Boolean] $ExcelCachingUnusedFiles, + [Parameter()] [System.Boolean] $ExcelAbortOnRefreshOnOpenFail, + [Parameter()] [System.Int32] $ExcelAutomaticVolatileFunctionCacheLifetime, + [Parameter()] [System.Int32] $ExcelConcurrentDataRequestsPerSessionMax, + [Parameter()] [System.String] $ExcelDefaultWorkbookCalcMode, + [Parameter()] [System.Boolean] $ExcelRestExternalDataEnabled, + [Parameter()] [System.Int32] $ExcelChartAndImageSizeMax, + [Parameter()] [System.String] $ExternalURL, + [Parameter()] [System.String] $FarmOU, - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.String] $InternalURL, + [Parameter()] [System.String] $LogLocation, + [Parameter()] [System.Int32] $LogRetentionInDays, + [Parameter()] [System.String] $LogVerbosity, + [Parameter()] [System.Int32] $MaxMemoryCacheSizeInMB, + [Parameter()] [System.Int32] $MaxTranslationCharacterCount, + [Parameter()] [System.Boolean] $OpenFromUncEnabled, + [Parameter()] [System.Boolean] $OpenFromUrlEnabled, + [Parameter()] [System.Boolean] $OpenFromUrlThrottlingEnabled, + [Parameter()] [System.String] $Proxy, + [Parameter()] [System.Int32] $RecycleActiveProcessCount, + [Parameter()] [System.String] $RenderingLocalCacheLocation, + [Parameter()] [System.Boolean] $SSLOffloaded, + [Parameter()] [System.Boolean] $TranslationEnabled, + [Parameter()] [System.String] $TranslationServiceAddress, + [Parameter()] [System.String] $TranslationServiceAppId, + [Parameter()] [System.Boolean] $AllowOutboundHttp, + [Parameter()] [System.Boolean] $ExcelUseEffectiveUserName, + [Parameter()] [System.String] $S2SCertificateName, + [Parameter()] [System.Boolean] $RemovePersonalInformationFromLogs, + [Parameter()] [System.Boolean] $PicturePasteDisabled ) @@ -239,154 +288,203 @@ function Set-TargetResource [CmdletBinding()] param ( + [Parameter()] [System.Boolean] $AllowCEIP, + [Parameter()] [System.Boolean] $AllowHttp, + [Parameter()] [System.Boolean] $AllowHttpSecureStoreConnections, + [Parameter()] [System.String] $CacheLocation, + [Parameter()] [System.Int32] $CacheSizeInGB, + [Parameter()] [System.String] $CertificateName, + [Parameter()] [System.Boolean] $ClipartEnabled, + [Parameter()] [System.Int32] $DocumentInfoCacheSize, + [Parameter()] [System.Boolean] $EditingEnabled, + [Parameter()] [System.Boolean] $ExcelAllowExternalData, + [Parameter()] [System.Int32] $ExcelConnectionLifetime, + [Parameter()] [System.Int32] $ExcelExternalDataCacheLifetime, + [Parameter()] [System.Int32] $ExcelPrivateBytesMax, + [Parameter()] [System.Int32] $ExcelRequestDurationMax, + [Parameter()] [System.Int32] $ExcelSessionTimeout, + [Parameter()] [System.Boolean] $ExcelUdfsAllowed, + [Parameter()] [System.Boolean] $ExcelWarnOnDataRefresh, + [Parameter()] [System.Int32] $ExcelWorkbookSizeMax, + [Parameter()] [System.Int32] $ExcelMemoryCacheThreshold, + [Parameter()] [System.Int32] $ExcelUnusedObjectAgeMax, + [Parameter()] [System.Boolean] $ExcelCachingUnusedFiles, + [Parameter()] [System.Boolean] $ExcelAbortOnRefreshOnOpenFail, + [Parameter()] [System.Int32] $ExcelAutomaticVolatileFunctionCacheLifetime, + [Parameter()] [System.Int32] $ExcelConcurrentDataRequestsPerSessionMax, + [Parameter()] [System.String] $ExcelDefaultWorkbookCalcMode, + [Parameter()] [System.Boolean] $ExcelRestExternalDataEnabled, + [Parameter()] [System.Int32] $ExcelChartAndImageSizeMax, + [Parameter()] [System.String] $ExternalURL, + [Parameter()] [System.String] $FarmOU, - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.String] $InternalURL, + [Parameter()] [System.String] $LogLocation, + [Parameter()] [System.Int32] $LogRetentionInDays, + [Parameter()] [System.String] $LogVerbosity, + [Parameter()] [System.Int32] $MaxMemoryCacheSizeInMB, + [Parameter()] [System.Int32] $MaxTranslationCharacterCount, + [Parameter()] [System.Boolean] $OpenFromUncEnabled, + [Parameter()] [System.Boolean] $OpenFromUrlEnabled, + [Parameter()] [System.Boolean] $OpenFromUrlThrottlingEnabled, + [Parameter()] [System.String] $Proxy, + [Parameter()] [System.Int32] $RecycleActiveProcessCount, + [Parameter()] [System.String] $RenderingLocalCacheLocation, + [Parameter()] [System.Boolean] $SSLOffloaded, + [Parameter()] [System.Boolean] $TranslationEnabled, + [Parameter()] [System.String] $TranslationServiceAddress, + [Parameter()] [System.String] $TranslationServiceAppId, + [Parameter()] [System.Boolean] $AllowOutboundHttp, + [Parameter()] [System.Boolean] $ExcelUseEffectiveUserName, + [Parameter()] [System.String] $S2SCertificateName, + [Parameter()] [System.Boolean] $RemovePersonalInformationFromLogs, + [Parameter()] [System.Boolean] $PicturePasteDisabled ) @@ -421,154 +519,203 @@ function Test-TargetResource [OutputType([System.Boolean])] param ( + [Parameter()] [System.Boolean] $AllowCEIP, + [Parameter()] [System.Boolean] $AllowHttp, + [Parameter()] [System.Boolean] $AllowHttpSecureStoreConnections, + [Parameter()] [System.String] $CacheLocation, + [Parameter()] [System.Int32] $CacheSizeInGB, + [Parameter()] [System.String] $CertificateName, + [Parameter()] [System.Boolean] $ClipartEnabled, + [Parameter()] [System.Int32] $DocumentInfoCacheSize, + [Parameter()] [System.Boolean] $EditingEnabled, + [Parameter()] [System.Boolean] $ExcelAllowExternalData, + [Parameter()] [System.Int32] $ExcelConnectionLifetime, + [Parameter()] [System.Int32] $ExcelExternalDataCacheLifetime, + [Parameter()] [System.Int32] $ExcelPrivateBytesMax, + [Parameter()] [System.Int32] $ExcelRequestDurationMax, + [Parameter()] [System.Int32] $ExcelSessionTimeout, + [Parameter()] [System.Boolean] $ExcelUdfsAllowed, + [Parameter()] [System.Boolean] $ExcelWarnOnDataRefresh, + [Parameter()] [System.Int32] $ExcelWorkbookSizeMax, + [Parameter()] [System.Int32] $ExcelMemoryCacheThreshold, + [Parameter()] [System.Int32] $ExcelUnusedObjectAgeMax, + [Parameter()] [System.Boolean] $ExcelCachingUnusedFiles, + [Parameter()] [System.Boolean] $ExcelAbortOnRefreshOnOpenFail, + [Parameter()] [System.Int32] $ExcelAutomaticVolatileFunctionCacheLifetime, + [Parameter()] [System.Int32] $ExcelConcurrentDataRequestsPerSessionMax, + [Parameter()] [System.String] $ExcelDefaultWorkbookCalcMode, + [Parameter()] [System.Boolean] $ExcelRestExternalDataEnabled, + [Parameter()] [System.Int32] $ExcelChartAndImageSizeMax, + [Parameter()] [System.String] $ExternalURL, + [Parameter()] [System.String] $FarmOU, - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.String] $InternalURL, + [Parameter()] [System.String] $LogLocation, + [Parameter()] [System.Int32] $LogRetentionInDays, + [Parameter()] [System.String] $LogVerbosity, + [Parameter()] [System.Int32] $MaxMemoryCacheSizeInMB, + [Parameter()] [System.Int32] $MaxTranslationCharacterCount, + [Parameter()] [System.Boolean] $OpenFromUncEnabled, + [Parameter()] [System.Boolean] $OpenFromUrlEnabled, + [Parameter()] [System.Boolean] $OpenFromUrlThrottlingEnabled, + [Parameter()] [System.String] $Proxy, + [Parameter()] [System.Int32] $RecycleActiveProcessCount, + [Parameter()] [System.String] $RenderingLocalCacheLocation, + [Parameter()] [System.Boolean] $SSLOffloaded, + [Parameter()] [System.Boolean] $TranslationEnabled, + [Parameter()] [System.String] $TranslationServiceAddress, + [Parameter()] [System.String] $TranslationServiceAppId, + [Parameter()] [System.Boolean] $AllowOutboundHttp, + [Parameter()] [System.Boolean] $ExcelUseEffectiveUserName, + [Parameter()] [System.String] $S2SCertificateName, + [Parameter()] [System.Boolean] $RemovePersonalInformationFromLogs, + [Parameter()] [System.Boolean] $PicturePasteDisabled ) diff --git a/lib/puppet_x/dsc_resources/OfficeOnlineServerDsc/DSCResources/MSFT_OfficeOnlineServerInstallLanguagePack/MSFT_OfficeOnlineServerInstallLanguagePack.psm1 b/lib/puppet_x/dsc_resources/OfficeOnlineServerDsc/DSCResources/MSFT_OfficeOnlineServerInstallLanguagePack/MSFT_OfficeOnlineServerInstallLanguagePack.psm1 new file mode 100644 index 000000000..6e56166d7 --- /dev/null +++ b/lib/puppet_x/dsc_resources/OfficeOnlineServerDsc/DSCResources/MSFT_OfficeOnlineServerInstallLanguagePack/MSFT_OfficeOnlineServerInstallLanguagePack.psm1 @@ -0,0 +1,167 @@ +$Script:UninstallPath = "SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" +$script:InstallKeyPattern = "Office1(5)|(6).WacServerLpk." + +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter(Mandatory = $true)] + [ValidateSet("Present","Absent")] + [System.String] + $Ensure, + + [Parameter(Mandatory = $true)] + [System.String] + $BinaryDir, + + [Parameter(Mandatory = $true)] + [System.String] + $Language + ) + + Write-Verbose -Message "Getting install status of the $Language Language Pack" + + if ($Ensure -eq "Absent") + { + throw "Uninstallation of Language Packs is not currently supported by OfficeOnlineServer Dsc" + } + + Write-Verbose -Message "Update is for the $Language language" + + $matchPath = "HKEY_LOCAL_MACHINE\\$($Script:UninstallPath.Replace('\','\\'))" + ` + "\\$script:InstallKeyPattern" + $Language + $wacPath = Get-ChildItem -Path "HKLM:\$Script:UninstallPath" | Where-Object -FilterScript { + $_.Name -match $matchPath + } + + if ($null -ne $wacPath) + { + Write-Verbose -Message "Language Pack $Language is found" + return @{ + BinaryDir = $BinaryDir + Language = $Language + Ensure = "Present" + } + } + else + { + Write-Verbose -Message "Language Pack $Language is NOT found" + return @{ + BinaryDir = $BinaryDir + Language = $Language + Ensure = "Absent" + } + } +} + + +function Set-TargetResource +{ + # Supressing the global variable use to allow passing DSC the reboot message + [CmdletBinding()] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidGlobalVars", "")] + param + ( + [Parameter(Mandatory = $true)] + [ValidateSet("Present","Absent")] + [System.String] + $Ensure, + + [Parameter(Mandatory = $true)] + [System.String] + $BinaryDir, + + [Parameter(Mandatory = $true)] + [System.String] + $Language + ) + + Write-Verbose -Message "Setting install status of Office Online Language Pack" + + if ($Ensure -eq "Absent") + { + throw [Exception] ("OfficeOnlineServerDsc does not support uninstalling " + ` + "Language Packs. Please remove this manually.") + return + } + + # Check if Binary folder exists + if (-not(Test-Path -Path $BinaryDir)) + { + throw "Specified path cannot be found. {$BinaryDir}" + } + + + Write-Verbose -Message "Writing install config file" + + Write-Verbose -Message "Beginning installation of the Office Online Server Language Pack" + + $setupExe = Join-Path -Path $BinaryDir -ChildPath "setup.exe" + + $installer = Start-Process -FilePath $setupExe ` + -ArgumentList '/config .\files\setupsilent\config.xml' ` + -Wait ` + -PassThru + + switch ($installer.ExitCode) + { + 0 { + Write-Verbose -Message "Office Online Server Language Pack binary installation complete" + } + 17022 { + Write-Verbose -Message "Office Online Server Language Pack binary installation complete. Reboot required." + $global:DSCMachineStatus = 1 + } + Default { + throw "Office Online Server Language Pack install failed, exit code was $($installer.ExitCode)" + } + } +} + + +function Test-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [ValidateSet("Present","Absent")] + [System.String] + $Ensure, + + [Parameter(Mandatory = $true)] + [System.String] + $BinaryDir, + + [Parameter(Mandatory = $true)] + [System.String] + $Language +) + + Write-Verbose -Message "Testing install status of Office Online Server $Language Language Pack" + + + if ($Ensure -eq "Absent") + { + throw [Exception] ("OfficeOnlineServerDsc does not support uninstalling Office Online Server " + ` + "Language Packs. Please remove this manually.") + return + } + + $CurrentValues = Get-TargetResource @PSBoundParameters + + if($CurrentValues.Ensure -eq $Ensure) + { + Write-Verbose -Message "Language Pack $Language is already installed on the server" + return $true + } + else + { + return $false + } +} + +Export-ModuleMember -Function *-TargetResource diff --git a/lib/puppet_x/dsc_resources/OfficeOnlineServerDsc/DSCResources/MSFT_OfficeOnlineServerInstallLanguagePack/MSFT_OfficeOnlineServerInstallLanguagePack.schema.mof b/lib/puppet_x/dsc_resources/OfficeOnlineServerDsc/DSCResources/MSFT_OfficeOnlineServerInstallLanguagePack/MSFT_OfficeOnlineServerInstallLanguagePack.schema.mof new file mode 100644 index 000000000..3962b84aa --- /dev/null +++ b/lib/puppet_x/dsc_resources/OfficeOnlineServerDsc/DSCResources/MSFT_OfficeOnlineServerInstallLanguagePack/MSFT_OfficeOnlineServerInstallLanguagePack.schema.mof @@ -0,0 +1,8 @@ + +[ClassVersion("1.0.0.0"), FriendlyName("OfficeOnlineServerInstallLanguagePack")] +class MSFT_OfficeOnlineServerInstallLanguagePack : OMI_BaseResource +{ + [Key, Description("Set to 'present' to specificy that the product should be installed."), ValueMap{"Present","Absent"}, Values{"Present","Absent"}] String Ensure; + [Key, Description("Path to setup.exe")] String BinaryDir; + [Required, Description("Language code for the package")] String Language; +}; diff --git a/lib/puppet_x/dsc_resources/OfficeOnlineServerDsc/DSCResources/MSFT_OfficeOnlineServerMachine/MSFT_OfficeOnlineServerMachine.psm1 b/lib/puppet_x/dsc_resources/OfficeOnlineServerDsc/DSCResources/MSFT_OfficeOnlineServerMachine/MSFT_OfficeOnlineServerMachine.psm1 index 91543055a..124e408e8 100644 --- a/lib/puppet_x/dsc_resources/OfficeOnlineServerDsc/DSCResources/MSFT_OfficeOnlineServerMachine/MSFT_OfficeOnlineServerMachine.psm1 +++ b/lib/puppet_x/dsc_resources/OfficeOnlineServerDsc/DSCResources/MSFT_OfficeOnlineServerMachine/MSFT_OfficeOnlineServerMachine.psm1 @@ -16,19 +16,20 @@ function Get-TargetResource [OutputType([System.Collections.Hashtable])] param ( + [Parameter()] [ValidateSet("Present","Absent")] [System.String] $Ensure = "Present", + [Parameter()] [System.String[]] $Roles, - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.String] $MachineToJoin ) - Import-Module -Name OfficeWebApps -ErrorAction Stop $officeWebAppsMachine = $null @@ -77,14 +78,16 @@ function Set-TargetResource [CmdletBinding()] param ( + [Parameter()] [ValidateSet("Present","Absent")] [System.String] $Ensure = "Present", + [Parameter()] [System.String[]] $Roles, - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.String] $MachineToJoin ) @@ -129,14 +132,16 @@ function Test-TargetResource [OutputType([System.Boolean])] param ( + [Parameter()] [ValidateSet("Present","Absent")] [System.String] $Ensure = "Present", + [Parameter()] [System.String[]] $Roles, - [parameter(Mandatory = $true)] + [Parameter(Mandatory = $true)] [System.String] $MachineToJoin ) diff --git a/lib/puppet_x/dsc_resources/OfficeOnlineServerDsc/OfficeOnlineServerDsc.psd1 b/lib/puppet_x/dsc_resources/OfficeOnlineServerDsc/OfficeOnlineServerDsc.psd1 index c309f3669..8c6110fb2 100644 --- a/lib/puppet_x/dsc_resources/OfficeOnlineServerDsc/OfficeOnlineServerDsc.psd1 +++ b/lib/puppet_x/dsc_resources/OfficeOnlineServerDsc/OfficeOnlineServerDsc.psd1 @@ -1,9 +1,9 @@ -# +# # Module manifest for module 'OfficeOnlineServerDsc' # -# Generated by: Jason Walker +# Generated by: Nik Charlebois # -# Generated on: 2/3/2016 +# Generated on: 2018-02-08 # @{ @@ -12,7 +12,7 @@ # RootModule = '' # Version number of this module. -ModuleVersion = '1.0.0.0' +ModuleVersion = '1.2.0.0' # ID used to uniquely identify this module GUID = '7514bb93-d3e4-40b2-98e7-3404e9674c1c' @@ -24,7 +24,7 @@ Author = 'Microsoft Corporation' CompanyName = 'Microsoft Corporation' # Copyright statement for this module -Copyright = '(c) 2016 Microsoft. All rights reserved.' +Copyright = '(c) 2018 Microsoft. All rights reserved.' # Description of the functionality provided by this module Description = 'The OfficeOnlineServerDsc module provides the ability to install Office Online Server (formerly known as Office Web App Server).' @@ -111,10 +111,8 @@ PrivateData = @{ # IconUri = '' # ReleaseNotes of this module - ReleaseNotes = '* Added documentation to the module to finalise for release -* Renamed resources to shorten names before release - * "OfficeOnlineServerWebAppsFarm" becomes "OfficeOnlineServerFarm" - * "OfficeOnlineServerWebAppsMachine" becomes "OfficeOnlineServerMachine" + ReleaseNotes = '* Added support for Multiple Language Packs installation; + ' } # End of PSData hashtable @@ -123,3 +121,4 @@ PrivateData = @{ } + diff --git a/types.md b/types.md index 75c918bcb..708e6275a 100644 --- a/types.md +++ b/types.md @@ -11,6 +11,7 @@ dsc_auditpolicyoption | [AuditPolicyOption](https://github.com/puppetlabs/puppet dsc_auditpolicysubcategory | [AuditPolicySubcategory](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/AuditPolicyDsc/DSCResources/MSFT_AuditPolicySubcategory) | import/dsc_resources/AuditPolicyDsc/DSCResources/MSFT_AuditPolicySubcategory/MSFT_AuditPolicySubcategory.schema.mof dsc_officeonlineserverfarm | [OfficeOnlineServerFarm](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/OfficeOnlineServerDsc/DSCResources/MSFT_OfficeOnlineServerFarm) | import/dsc_resources/OfficeOnlineServerDsc/DSCResources/MSFT_OfficeOnlineServerFarm/MSFT_OfficeOnlineServerFarm.schema.mof dsc_officeonlineserverinstall | [OfficeOnlineServerInstall](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/OfficeOnlineServerDsc/DSCResources/MSFT_OfficeOnlineServerInstall) | import/dsc_resources/OfficeOnlineServerDsc/DSCResources/MSFT_OfficeOnlineServerInstall/MSFT_OfficeOnlineServerInstall.schema.mof +dsc_officeonlineserverinstalllanguagepack | [OfficeOnlineServerInstallLanguagePack](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/OfficeOnlineServerDsc/DSCResources/MSFT_OfficeOnlineServerInstallLanguagePack) | import/dsc_resources/OfficeOnlineServerDsc/DSCResources/MSFT_OfficeOnlineServerInstallLanguagePack/MSFT_OfficeOnlineServerInstallLanguagePack.schema.mof dsc_officeonlineservermachine | [OfficeOnlineServerMachine](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/OfficeOnlineServerDsc/DSCResources/MSFT_OfficeOnlineServerMachine) | import/dsc_resources/OfficeOnlineServerDsc/DSCResources/MSFT_OfficeOnlineServerMachine/MSFT_OfficeOnlineServerMachine.schema.mof dsc_archive | [Archive](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/PSDesiredStateConfiguration/DSCResources/MSFT_ArchiveResource) | import/dsc_resources/PSDesiredStateConfiguration/DSCResources/MSFT_ArchiveResource/MSFT_ArchiveResource.schema.mof dsc_environment | [Environment](https://github.com/puppetlabs/puppetlabs-dsc/tree/master/build/vendor/wmf_dsc_resources/PSDesiredStateConfiguration/DSCResources/MSFT_EnvironmentResource) | import/dsc_resources/PSDesiredStateConfiguration/DSCResources/MSFT_EnvironmentResource/MSFT_EnvironmentResource.schema.mof From 38b4f222c036df78aacaabd059e1348bc54b7d69 Mon Sep 17 00:00:00 2001 From: James Pogran Date: Fri, 9 Feb 2018 20:36:37 -0500 Subject: [PATCH 07/25] (MODULES-6592) Update SecurityPolicyDsc to 2.2.0.0 This commit updates SecurityPolicyDsc to the latest gallery version --- dsc_resource_release_tags.yml | 2 +- lib/puppet/type/dsc_accountpolicy.rb | 337 ++++ lib/puppet/type/dsc_securityoption.rb | 1598 +++++++++++++++++ lib/puppet/type/dsc_securitysetting.rb | 462 ----- lib/puppet/type/dsc_securitytemplate.rb | 2 +- lib/puppet/type/dsc_userrightsassignment.rb | 2 +- .../MSFT_AccountPolicy/AccountPolicyData.psd1 | 117 ++ .../MSFT_AccountPolicy.psm1 | 312 ++++ .../MSFT_AccountPolicy.schema.mof | 21 + .../en-US/MSFT_AccountPolicy.strings.psd1 | 11 + .../MSFT_SecurityOption.psm1 | 1185 ++++++++++++ .../MSFT_SecurityOption.schema.mof | 102 ++ .../SecurityOptionData.psd1 | 870 +++++++++ .../en-US/MSFT_SecurityOption.strings.psd1 | 11 + .../MSFT_SecuritySetting.psm1 | 465 ----- .../MSFT_SecuritySetting.schema.mof | 26 - .../en-US/MSFT_SecuritySetting.strings.psd1 | 8 - .../MSFT_SecurityTemplate.psm1 | 14 +- .../MSFT_UserRightsAssignment.psm1 | 149 +- .../MSFT_UserRightsAssignment.strings.psd1 | 6 +- .../SecurityPolicyResourceHelper.psm1 | 322 +++- .../SecurityPolicyDsc/SecurityPolicyDsc.psd1 | 7 +- types.md | 3 +- 23 files changed, 4882 insertions(+), 1150 deletions(-) create mode 100644 lib/puppet/type/dsc_accountpolicy.rb create mode 100644 lib/puppet/type/dsc_securityoption.rb delete mode 100644 lib/puppet/type/dsc_securitysetting.rb create mode 100644 lib/puppet_x/dsc_resources/SecurityPolicyDsc/DSCResources/MSFT_AccountPolicy/AccountPolicyData.psd1 create mode 100644 lib/puppet_x/dsc_resources/SecurityPolicyDsc/DSCResources/MSFT_AccountPolicy/MSFT_AccountPolicy.psm1 create mode 100644 lib/puppet_x/dsc_resources/SecurityPolicyDsc/DSCResources/MSFT_AccountPolicy/MSFT_AccountPolicy.schema.mof create mode 100644 lib/puppet_x/dsc_resources/SecurityPolicyDsc/DSCResources/MSFT_AccountPolicy/en-US/MSFT_AccountPolicy.strings.psd1 create mode 100644 lib/puppet_x/dsc_resources/SecurityPolicyDsc/DSCResources/MSFT_SecurityOption/MSFT_SecurityOption.psm1 create mode 100644 lib/puppet_x/dsc_resources/SecurityPolicyDsc/DSCResources/MSFT_SecurityOption/MSFT_SecurityOption.schema.mof create mode 100644 lib/puppet_x/dsc_resources/SecurityPolicyDsc/DSCResources/MSFT_SecurityOption/SecurityOptionData.psd1 create mode 100644 lib/puppet_x/dsc_resources/SecurityPolicyDsc/DSCResources/MSFT_SecurityOption/en-US/MSFT_SecurityOption.strings.psd1 delete mode 100644 lib/puppet_x/dsc_resources/SecurityPolicyDsc/DSCResources/MSFT_SecuritySetting/MSFT_SecuritySetting.psm1 delete mode 100644 lib/puppet_x/dsc_resources/SecurityPolicyDsc/DSCResources/MSFT_SecuritySetting/MSFT_SecuritySetting.schema.mof delete mode 100644 lib/puppet_x/dsc_resources/SecurityPolicyDsc/DSCResources/MSFT_SecuritySetting/en-US/MSFT_SecuritySetting.strings.psd1 diff --git a/dsc_resource_release_tags.yml b/dsc_resource_release_tags.yml index 11558ec5f..5c73643be 100644 --- a/dsc_resource_release_tags.yml +++ b/dsc_resource_release_tags.yml @@ -1,7 +1,7 @@ --- AuditPolicyDsc: 1.1.0.0-PSGallery OfficeOnlineServerDsc: 1.2.0.0-PSGallery -SecurityPolicyDsc: 1.5.0.0-PSGallery +SecurityPolicyDsc: 2.2.0.0-PSGallery SharePointDsc: 1.8.0.0-PSGallery SqlServerDsc: 11.0.0.0-PSGallery StorageDsc: 4.0.0.0-PSGallery diff --git a/lib/puppet/type/dsc_accountpolicy.rb b/lib/puppet/type/dsc_accountpolicy.rb new file mode 100644 index 000000000..4afcef355 --- /dev/null +++ b/lib/puppet/type/dsc_accountpolicy.rb @@ -0,0 +1,337 @@ +require 'pathname' + +Puppet::Type.newtype(:dsc_accountpolicy) do + require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' + require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' + + + @doc = %q{ + The DSC AccountPolicy resource type. + Automatically generated from + 'SecurityPolicyDsc/DSCResources/MSFT_AccountPolicy/MSFT_AccountPolicy.schema.mof' + + To learn more about PowerShell Desired State Configuration, please + visit https://technet.microsoft.com/en-us/library/dn249912.aspx. + + For more information about built-in DSC Resources, please visit + https://technet.microsoft.com/en-us/library/dn249921.aspx. + + For more information about xDsc Resources, please visit + https://github.com/PowerShell/DscResources. + } + + validate do + fail('dsc_name is a required attribute') if self[:dsc_name].nil? + end + + def dscmeta_resource_friendly_name; 'AccountPolicy' end + def dscmeta_resource_name; 'MSFT_AccountPolicy' end + def dscmeta_module_name; 'SecurityPolicyDsc' end + def dscmeta_module_version; '2.2.0.0' end + + newparam(:name, :namevar => true ) do + end + + ensurable do + newvalue(:exists?) { provider.exists? } + newvalue(:present) { provider.create } + defaultto { :present } + end + + # Name: PsDscRunAsCredential + # Type: MSFT_Credential + # IsMandatory: False + # Values: None + newparam(:dsc_psdscrunascredential) do + def mof_type; 'MSFT_Credential' end + def mof_is_embedded?; true end + desc "PsDscRunAsCredential" + validate do |value| + unless value.kind_of?(Hash) + fail("Invalid value '#{value}'. Should be a hash") + end + PuppetX::Dsc::TypeHelpers.validate_MSFT_Credential("Credential", value) + end + end + + # Name: Name + # Type: string + # IsMandatory: True + # Values: None + newparam(:dsc_name) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Name - A unique name of the AccountPolicy resource instance. This is not used during configuration." + isrequired + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Enforce_password_history + # Type: uint32 + # IsMandatory: False + # Values: None + newparam(:dsc_enforce_password_history) do + def mof_type; 'uint32' end + def mof_is_embedded?; false end + desc "Enforce_password_history" + validate do |value| + unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) + fail("Invalid value #{value}. Should be a unsigned Integer") + end + end + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_integer(value) + end + end + + # Name: Maximum_Password_Age + # Type: uint32 + # IsMandatory: False + # Values: None + newparam(:dsc_maximum_password_age) do + def mof_type; 'uint32' end + def mof_is_embedded?; false end + desc "Maximum_Password_Age" + validate do |value| + unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) + fail("Invalid value #{value}. Should be a unsigned Integer") + end + end + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_integer(value) + end + end + + # Name: Minimum_Password_Age + # Type: uint32 + # IsMandatory: False + # Values: None + newparam(:dsc_minimum_password_age) do + def mof_type; 'uint32' end + def mof_is_embedded?; false end + desc "Minimum_Password_Age" + validate do |value| + unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) + fail("Invalid value #{value}. Should be a unsigned Integer") + end + end + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_integer(value) + end + end + + # Name: Minimum_Password_Length + # Type: uint32 + # IsMandatory: False + # Values: None + newparam(:dsc_minimum_password_length) do + def mof_type; 'uint32' end + def mof_is_embedded?; false end + desc "Minimum_Password_Length" + validate do |value| + unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) + fail("Invalid value #{value}. Should be a unsigned Integer") + end + end + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_integer(value) + end + end + + # Name: Password_must_meet_complexity_requirements + # Type: string + # IsMandatory: False + # Values: ["Enabled", "Disabled"] + newparam(:dsc_password_must_meet_complexity_requirements) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Password_must_meet_complexity_requirements - Valid values are Enabled, Disabled." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + unless ['Enabled', 'enabled', 'Disabled', 'disabled'].include?(value) + fail("Invalid value '#{value}'. Valid values are Enabled, Disabled") + end + end + end + + # Name: Store_passwords_using_reversible_encryption + # Type: string + # IsMandatory: False + # Values: ["Enabled", "Disabled"] + newparam(:dsc_store_passwords_using_reversible_encryption) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Store_passwords_using_reversible_encryption - Valid values are Enabled, Disabled." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + unless ['Enabled', 'enabled', 'Disabled', 'disabled'].include?(value) + fail("Invalid value '#{value}'. Valid values are Enabled, Disabled") + end + end + end + + # Name: Account_lockout_duration + # Type: uint32 + # IsMandatory: False + # Values: None + newparam(:dsc_account_lockout_duration) do + def mof_type; 'uint32' end + def mof_is_embedded?; false end + desc "Account_lockout_duration" + validate do |value| + unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) + fail("Invalid value #{value}. Should be a unsigned Integer") + end + end + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_integer(value) + end + end + + # Name: Account_lockout_threshold + # Type: uint32 + # IsMandatory: False + # Values: None + newparam(:dsc_account_lockout_threshold) do + def mof_type; 'uint32' end + def mof_is_embedded?; false end + desc "Account_lockout_threshold" + validate do |value| + unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) + fail("Invalid value #{value}. Should be a unsigned Integer") + end + end + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_integer(value) + end + end + + # Name: Reset_account_lockout_counter_after + # Type: uint32 + # IsMandatory: False + # Values: None + newparam(:dsc_reset_account_lockout_counter_after) do + def mof_type; 'uint32' end + def mof_is_embedded?; false end + desc "Reset_account_lockout_counter_after" + validate do |value| + unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) + fail("Invalid value #{value}. Should be a unsigned Integer") + end + end + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_integer(value) + end + end + + # Name: Enforce_user_logon_restrictions + # Type: string + # IsMandatory: False + # Values: ["Enabled", "Disabled"] + newparam(:dsc_enforce_user_logon_restrictions) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Enforce_user_logon_restrictions - Valid values are Enabled, Disabled." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + unless ['Enabled', 'enabled', 'Disabled', 'disabled'].include?(value) + fail("Invalid value '#{value}'. Valid values are Enabled, Disabled") + end + end + end + + # Name: Maximum_lifetime_for_service_ticket + # Type: uint32 + # IsMandatory: False + # Values: None + newparam(:dsc_maximum_lifetime_for_service_ticket) do + def mof_type; 'uint32' end + def mof_is_embedded?; false end + desc "Maximum_lifetime_for_service_ticket" + validate do |value| + unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) + fail("Invalid value #{value}. Should be a unsigned Integer") + end + end + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_integer(value) + end + end + + # Name: Maximum_lifetime_for_user_ticket + # Type: uint32 + # IsMandatory: False + # Values: None + newparam(:dsc_maximum_lifetime_for_user_ticket) do + def mof_type; 'uint32' end + def mof_is_embedded?; false end + desc "Maximum_lifetime_for_user_ticket" + validate do |value| + unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) + fail("Invalid value #{value}. Should be a unsigned Integer") + end + end + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_integer(value) + end + end + + # Name: Maximum_lifetime_for_user_ticket_renewal + # Type: uint32 + # IsMandatory: False + # Values: None + newparam(:dsc_maximum_lifetime_for_user_ticket_renewal) do + def mof_type; 'uint32' end + def mof_is_embedded?; false end + desc "Maximum_lifetime_for_user_ticket_renewal" + validate do |value| + unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) + fail("Invalid value #{value}. Should be a unsigned Integer") + end + end + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_integer(value) + end + end + + # Name: Maximum_tolerance_for_computer_clock_synchronization + # Type: uint32 + # IsMandatory: False + # Values: None + newparam(:dsc_maximum_tolerance_for_computer_clock_synchronization) do + def mof_type; 'uint32' end + def mof_is_embedded?; false end + desc "Maximum_tolerance_for_computer_clock_synchronization" + validate do |value| + unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) + fail("Invalid value #{value}. Should be a unsigned Integer") + end + end + munge do |value| + PuppetX::Dsc::TypeHelpers.munge_integer(value) + end + end + + + def builddepends + pending_relations = super() + PuppetX::Dsc::TypeHelpers.ensure_reboot_relationship(self, pending_relations) + end +end + +Puppet::Type.type(:dsc_accountpolicy).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do + confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) + defaultfor :operatingsystem => :windows + + mk_resource_methods +end diff --git a/lib/puppet/type/dsc_securityoption.rb b/lib/puppet/type/dsc_securityoption.rb new file mode 100644 index 000000000..bc8d97677 --- /dev/null +++ b/lib/puppet/type/dsc_securityoption.rb @@ -0,0 +1,1598 @@ +require 'pathname' + +Puppet::Type.newtype(:dsc_securityoption) do + require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' + require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' + + + @doc = %q{ + The DSC SecurityOption resource type. + Automatically generated from + 'SecurityPolicyDsc/DSCResources/MSFT_SecurityOption/MSFT_SecurityOption.schema.mof' + + To learn more about PowerShell Desired State Configuration, please + visit https://technet.microsoft.com/en-us/library/dn249912.aspx. + + For more information about built-in DSC Resources, please visit + https://technet.microsoft.com/en-us/library/dn249921.aspx. + + For more information about xDsc Resources, please visit + https://github.com/PowerShell/DscResources. + } + + validate do + fail('dsc_name is a required attribute') if self[:dsc_name].nil? + end + + def dscmeta_resource_friendly_name; 'SecurityOption' end + def dscmeta_resource_name; 'MSFT_SecurityOption' end + def dscmeta_module_name; 'SecurityPolicyDsc' end + def dscmeta_module_version; '2.2.0.0' end + + newparam(:name, :namevar => true ) do + end + + ensurable do + newvalue(:exists?) { provider.exists? } + newvalue(:present) { provider.create } + defaultto { :present } + end + + # Name: PsDscRunAsCredential + # Type: MSFT_Credential + # IsMandatory: False + # Values: None + newparam(:dsc_psdscrunascredential) do + def mof_type; 'MSFT_Credential' end + def mof_is_embedded?; true end + desc "PsDscRunAsCredential" + validate do |value| + unless value.kind_of?(Hash) + fail("Invalid value '#{value}'. Should be a hash") + end + PuppetX::Dsc::TypeHelpers.validate_MSFT_Credential("Credential", value) + end + end + + # Name: Name + # Type: string + # IsMandatory: True + # Values: None + newparam(:dsc_name) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Name - Describes the security option to be managed. This could be anything as long as it is unique" + isrequired + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Accounts_Administrator_account_status + # Type: string + # IsMandatory: False + # Values: ["Enabled", "Disabled"] + newparam(:dsc_accounts_administrator_account_status) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Accounts_Administrator_account_status - Valid values are Enabled, Disabled." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + unless ['Enabled', 'enabled', 'Disabled', 'disabled'].include?(value) + fail("Invalid value '#{value}'. Valid values are Enabled, Disabled") + end + end + end + + # Name: Accounts_Block_Microsoft_accounts + # Type: string + # IsMandatory: False + # Values: ["This policy is disabled", "Users cant add Microsoft accounts", "Users cant add or log on with Microsoft accounts"] + newparam(:dsc_accounts_block_microsoft_accounts) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Accounts_Block_Microsoft_accounts - Valid values are This policy is disabled, Users cant add Microsoft accounts, Users cant add or log on with Microsoft accounts." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + unless ['This policy is disabled', 'this policy is disabled', 'Users cant add Microsoft accounts', 'users cant add microsoft accounts', 'Users cant add or log on with Microsoft accounts', 'users cant add or log on with microsoft accounts'].include?(value) + fail("Invalid value '#{value}'. Valid values are This policy is disabled, Users cant add Microsoft accounts, Users cant add or log on with Microsoft accounts") + end + end + end + + # Name: Accounts_Guest_account_status + # Type: string + # IsMandatory: False + # Values: ["Enabled", "Disabled"] + newparam(:dsc_accounts_guest_account_status) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Accounts_Guest_account_status - Valid values are Enabled, Disabled." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + unless ['Enabled', 'enabled', 'Disabled', 'disabled'].include?(value) + fail("Invalid value '#{value}'. Valid values are Enabled, Disabled") + end + end + end + + # Name: Accounts_Limit_local_account_use_of_blank_passwords_to_console_logon_only + # Type: string + # IsMandatory: False + # Values: ["Enabled", "Disabled"] + newparam(:dsc_accounts_limit_local_account_use_of_blank_passwords_to_console_logon_only) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Accounts_Limit_local_account_use_of_blank_passwords_to_console_logon_only - Valid values are Enabled, Disabled." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + unless ['Enabled', 'enabled', 'Disabled', 'disabled'].include?(value) + fail("Invalid value '#{value}'. Valid values are Enabled, Disabled") + end + end + end + + # Name: Accounts_Rename_administrator_account + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_accounts_rename_administrator_account) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Accounts_Rename_administrator_account" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Accounts_Rename_guest_account + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_accounts_rename_guest_account) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Accounts_Rename_guest_account" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Audit_Audit_the_access_of_global_system_objects + # Type: string + # IsMandatory: False + # Values: ["Enabled", "Disabled"] + newparam(:dsc_audit_audit_the_access_of_global_system_objects) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Audit_Audit_the_access_of_global_system_objects - Valid values are Enabled, Disabled." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + unless ['Enabled', 'enabled', 'Disabled', 'disabled'].include?(value) + fail("Invalid value '#{value}'. Valid values are Enabled, Disabled") + end + end + end + + # Name: Audit_Audit_the_use_of_Backup_and_Restore_privilege + # Type: string + # IsMandatory: False + # Values: ["Enabled", "Disabled"] + newparam(:dsc_audit_audit_the_use_of_backup_and_restore_privilege) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Audit_Audit_the_use_of_Backup_and_Restore_privilege - Valid values are Enabled, Disabled." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + unless ['Enabled', 'enabled', 'Disabled', 'disabled'].include?(value) + fail("Invalid value '#{value}'. Valid values are Enabled, Disabled") + end + end + end + + # Name: Audit_Force_audit_policy_subcategory_settings_Windows_Vista_or_later_to_override_audit_policy_category_settings + # Type: string + # IsMandatory: False + # Values: ["Enabled", "Disabled"] + newparam(:dsc_audit_force_audit_policy_subcategory_settings_windows_vista_or_later_to_override_audit_policy_category_settings) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Audit_Force_audit_policy_subcategory_settings_Windows_Vista_or_later_to_override_audit_policy_category_settings - Valid values are Enabled, Disabled." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + unless ['Enabled', 'enabled', 'Disabled', 'disabled'].include?(value) + fail("Invalid value '#{value}'. Valid values are Enabled, Disabled") + end + end + end + + # Name: Audit_Shut_down_system_immediately_if_unable_to_log_security_audits + # Type: string + # IsMandatory: False + # Values: ["Enabled", "Disabled"] + newparam(:dsc_audit_shut_down_system_immediately_if_unable_to_log_security_audits) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Audit_Shut_down_system_immediately_if_unable_to_log_security_audits - Valid values are Enabled, Disabled." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + unless ['Enabled', 'enabled', 'Disabled', 'disabled'].include?(value) + fail("Invalid value '#{value}'. Valid values are Enabled, Disabled") + end + end + end + + # Name: DCOM_Machine_Access_Restrictions_in_Security_Descriptor_Definition_Language_SDDL_syntax + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_dcom_machine_access_restrictions_in_security_descriptor_definition_language_sddl_syntax) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "DCOM_Machine_Access_Restrictions_in_Security_Descriptor_Definition_Language_SDDL_syntax" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: DCOM_Machine_Launch_Restrictions_in_Security_Descriptor_Definition_Language_SDDL_syntax + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_dcom_machine_launch_restrictions_in_security_descriptor_definition_language_sddl_syntax) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "DCOM_Machine_Launch_Restrictions_in_Security_Descriptor_Definition_Language_SDDL_syntax" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Devices_Allow_undock_without_having_to_log_on + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_devices_allow_undock_without_having_to_log_on) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Devices_Allow_undock_without_having_to_log_on" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Devices_Allowed_to_format_and_eject_removable_media + # Type: string + # IsMandatory: False + # Values: ["Administrators", "Administrators and Power Users", "Administrators and Interactive Users"] + newparam(:dsc_devices_allowed_to_format_and_eject_removable_media) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Devices_Allowed_to_format_and_eject_removable_media - Valid values are Administrators, Administrators and Power Users, Administrators and Interactive Users." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + unless ['Administrators', 'administrators', 'Administrators and Power Users', 'administrators and power users', 'Administrators and Interactive Users', 'administrators and interactive users'].include?(value) + fail("Invalid value '#{value}'. Valid values are Administrators, Administrators and Power Users, Administrators and Interactive Users") + end + end + end + + # Name: Devices_Prevent_users_from_installing_printer_drivers + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_devices_prevent_users_from_installing_printer_drivers) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Devices_Prevent_users_from_installing_printer_drivers" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Devices_Restrict_CD_ROM_access_to_locally_logged_on_user_only + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_devices_restrict_cd_rom_access_to_locally_logged_on_user_only) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Devices_Restrict_CD_ROM_access_to_locally_logged_on_user_only" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Devices_Restrict_floppy_access_to_locally_logged_on_user_only + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_devices_restrict_floppy_access_to_locally_logged_on_user_only) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Devices_Restrict_floppy_access_to_locally_logged_on_user_only" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Domain_controller_Allow_server_operators_to_schedule_tasks + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_domain_controller_allow_server_operators_to_schedule_tasks) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Domain_controller_Allow_server_operators_to_schedule_tasks" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Domain_controller_LDAP_server_signing_requirements + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_domain_controller_ldap_server_signing_requirements) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Domain_controller_LDAP_server_signing_requirements" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Domain_controller_Refuse_machine_account_password_changes + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_domain_controller_refuse_machine_account_password_changes) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Domain_controller_Refuse_machine_account_password_changes" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Domain_member_Digitally_encrypt_or_sign_secure_channel_data_always + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_domain_member_digitally_encrypt_or_sign_secure_channel_data_always) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Domain_member_Digitally_encrypt_or_sign_secure_channel_data_always" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Domain_member_Digitally_encrypt_secure_channel_data_when_possible + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_domain_member_digitally_encrypt_secure_channel_data_when_possible) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Domain_member_Digitally_encrypt_secure_channel_data_when_possible" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Domain_member_Digitally_sign_secure_channel_data_when_possible + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_domain_member_digitally_sign_secure_channel_data_when_possible) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Domain_member_Digitally_sign_secure_channel_data_when_possible" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Domain_member_Disable_machine_account_password_changes + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_domain_member_disable_machine_account_password_changes) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Domain_member_Disable_machine_account_password_changes" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Domain_member_Maximum_machine_account_password_age + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_domain_member_maximum_machine_account_password_age) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Domain_member_Maximum_machine_account_password_age" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Domain_member_Require_strong_Windows_2000_or_later_session_key + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_domain_member_require_strong_windows_2000_or_later_session_key) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Domain_member_Require_strong_Windows_2000_or_later_session_key" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Interactive_logon_Display_user_information_when_the_session_is_locked + # Type: string + # IsMandatory: False + # Values: ["User displayname, domain and user names", "User display name only", "Do not display user information"] + newparam(:dsc_interactive_logon_display_user_information_when_the_session_is_locked) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Interactive_logon_Display_user_information_when_the_session_is_locked - Valid values are User displayname, domain and user names, User display name only, Do not display user information." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + unless ['User displayname, domain and user names', 'user displayname, domain and user names', 'User display name only', 'user display name only', 'Do not display user information', 'do not display user information'].include?(value) + fail("Invalid value '#{value}'. Valid values are User displayname, domain and user names, User display name only, Do not display user information") + end + end + end + + # Name: Interactive_logon_Do_not_display_last_user_name + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_interactive_logon_do_not_display_last_user_name) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Interactive_logon_Do_not_display_last_user_name" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Interactive_logon_Do_not_require_CTRL_ALT_DEL + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_interactive_logon_do_not_require_ctrl_alt_del) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Interactive_logon_Do_not_require_CTRL_ALT_DEL" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Interactive_logon_Machine_account_lockout_threshold + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_interactive_logon_machine_account_lockout_threshold) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Interactive_logon_Machine_account_lockout_threshold" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Interactive_logon_Machine_inactivity_limit + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_interactive_logon_machine_inactivity_limit) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Interactive_logon_Machine_inactivity_limit" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Interactive_logon_Message_text_for_users_attempting_to_log_on + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_interactive_logon_message_text_for_users_attempting_to_log_on) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Interactive_logon_Message_text_for_users_attempting_to_log_on" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Interactive_logon_Message_title_for_users_attempting_to_log_on + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_interactive_logon_message_title_for_users_attempting_to_log_on) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Interactive_logon_Message_title_for_users_attempting_to_log_on" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Interactive_logon_Number_of_previous_logons_to_cache_in_case_domain_controller_is_not_available + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_interactive_logon_number_of_previous_logons_to_cache_in_case_domain_controller_is_not_available) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Interactive_logon_Number_of_previous_logons_to_cache_in_case_domain_controller_is_not_available" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Interactive_logon_Prompt_user_to_change_password_before_expiration + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_interactive_logon_prompt_user_to_change_password_before_expiration) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Interactive_logon_Prompt_user_to_change_password_before_expiration" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Interactive_logon_Require_Domain_Controller_authentication_to_unlock_workstation + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_interactive_logon_require_domain_controller_authentication_to_unlock_workstation) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Interactive_logon_Require_Domain_Controller_authentication_to_unlock_workstation" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Interactive_logon_Require_smart_card + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_interactive_logon_require_smart_card) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Interactive_logon_Require_smart_card" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Interactive_logon_Smart_card_removal_behavior + # Type: string + # IsMandatory: False + # Values: ["No Action", "Lock workstation", "Force logoff", "Disconnect if a remote Remote Desktop Services session"] + newparam(:dsc_interactive_logon_smart_card_removal_behavior) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Interactive_logon_Smart_card_removal_behavior - Valid values are No Action, Lock workstation, Force logoff, Disconnect if a remote Remote Desktop Services session." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + unless ['No Action', 'no action', 'Lock workstation', 'lock workstation', 'Force logoff', 'force logoff', 'Disconnect if a remote Remote Desktop Services session', 'disconnect if a remote remote desktop services session'].include?(value) + fail("Invalid value '#{value}'. Valid values are No Action, Lock workstation, Force logoff, Disconnect if a remote Remote Desktop Services session") + end + end + end + + # Name: Microsoft_network_client_Digitally_sign_communications_always + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_microsoft_network_client_digitally_sign_communications_always) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Microsoft_network_client_Digitally_sign_communications_always" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Microsoft_network_client_Digitally_sign_communications_if_server_agrees + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_microsoft_network_client_digitally_sign_communications_if_server_agrees) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Microsoft_network_client_Digitally_sign_communications_if_server_agrees" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Microsoft_network_client_Send_unencrypted_password_to_third_party_SMB_servers + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_microsoft_network_client_send_unencrypted_password_to_third_party_smb_servers) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Microsoft_network_client_Send_unencrypted_password_to_third_party_SMB_servers" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Microsoft_network_server_Amount_of_idle_time_required_before_suspending_session + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_microsoft_network_server_amount_of_idle_time_required_before_suspending_session) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Microsoft_network_server_Amount_of_idle_time_required_before_suspending_session" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Microsoft_network_server_Attempt_S4U2Self_to_obtain_claim_information + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_microsoft_network_server_attempt_s4u2self_to_obtain_claim_information) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Microsoft_network_server_Attempt_S4U2Self_to_obtain_claim_information" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Microsoft_network_server_Digitally_sign_communications_always + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_microsoft_network_server_digitally_sign_communications_always) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Microsoft_network_server_Digitally_sign_communications_always" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Microsoft_network_server_Digitally_sign_communications_if_client_agrees + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_microsoft_network_server_digitally_sign_communications_if_client_agrees) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Microsoft_network_server_Digitally_sign_communications_if_client_agrees" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Microsoft_network_server_Disconnect_clients_when_logon_hours_expire + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_microsoft_network_server_disconnect_clients_when_logon_hours_expire) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Microsoft_network_server_Disconnect_clients_when_logon_hours_expire" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Microsoft_network_server_Server_SPN_target_name_validation_level + # Type: string + # IsMandatory: False + # Values: ["Off", "Accept if provided by the client", "Required from client"] + newparam(:dsc_microsoft_network_server_server_spn_target_name_validation_level) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Microsoft_network_server_Server_SPN_target_name_validation_level - Valid values are Off, Accept if provided by the client, Required from client." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + unless ['Off', 'off', 'Accept if provided by the client', 'accept if provided by the client', 'Required from client', 'required from client'].include?(value) + fail("Invalid value '#{value}'. Valid values are Off, Accept if provided by the client, Required from client") + end + end + end + + # Name: Network_access_Allow_anonymous_SID_Name_translation + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_network_access_allow_anonymous_sid_name_translation) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Network_access_Allow_anonymous_SID_Name_translation" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Network_access_Do_not_allow_anonymous_enumeration_of_SAM_accounts + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_network_access_do_not_allow_anonymous_enumeration_of_sam_accounts) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Network_access_Do_not_allow_anonymous_enumeration_of_SAM_accounts" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Network_access_Do_not_allow_anonymous_enumeration_of_SAM_accounts_and_shares + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_network_access_do_not_allow_anonymous_enumeration_of_sam_accounts_and_shares) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Network_access_Do_not_allow_anonymous_enumeration_of_SAM_accounts_and_shares" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Network_access_Do_not_allow_storage_of_passwords_and_credentials_for_network_authentication + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_network_access_do_not_allow_storage_of_passwords_and_credentials_for_network_authentication) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Network_access_Do_not_allow_storage_of_passwords_and_credentials_for_network_authentication" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Network_access_Let_Everyone_permissions_apply_to_anonymous_users + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_network_access_let_everyone_permissions_apply_to_anonymous_users) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Network_access_Let_Everyone_permissions_apply_to_anonymous_users" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Network_access_Named_Pipes_that_can_be_accessed_anonymously + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_network_access_named_pipes_that_can_be_accessed_anonymously) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Network_access_Named_Pipes_that_can_be_accessed_anonymously" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Network_access_Remotely_accessible_registry_paths + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_network_access_remotely_accessible_registry_paths) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Network_access_Remotely_accessible_registry_paths" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Network_access_Remotely_accessible_registry_paths_and_subpaths + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_network_access_remotely_accessible_registry_paths_and_subpaths) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Network_access_Remotely_accessible_registry_paths_and_subpaths" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Network_access_Restrict_anonymous_access_to_Named_Pipes_and_Shares + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_network_access_restrict_anonymous_access_to_named_pipes_and_shares) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Network_access_Restrict_anonymous_access_to_Named_Pipes_and_Shares" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Network_access_Shares_that_can_be_accessed_anonymously + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_network_access_shares_that_can_be_accessed_anonymously) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Network_access_Shares_that_can_be_accessed_anonymously" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Network_access_Sharing_and_security_model_for_local_accounts + # Type: string + # IsMandatory: False + # Values: ["Classic - Local users authenticate as themselves", "Guest only - Local users authenticate as Guest"] + newparam(:dsc_network_access_sharing_and_security_model_for_local_accounts) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Network_access_Sharing_and_security_model_for_local_accounts - Valid values are Classic - Local users authenticate as themselves, Guest only - Local users authenticate as Guest." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + unless ['Classic - Local users authenticate as themselves', 'classic - local users authenticate as themselves', 'Guest only - Local users authenticate as Guest', 'guest only - local users authenticate as guest'].include?(value) + fail("Invalid value '#{value}'. Valid values are Classic - Local users authenticate as themselves, Guest only - Local users authenticate as Guest") + end + end + end + + # Name: Network_security_Allow_Local_System_to_use_computer_identity_for_NTLM + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_network_security_allow_local_system_to_use_computer_identity_for_ntlm) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Network_security_Allow_Local_System_to_use_computer_identity_for_NTLM" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Network_security_Allow_LocalSystem_NULL_session_fallback + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_network_security_allow_localsystem_null_session_fallback) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Network_security_Allow_LocalSystem_NULL_session_fallback" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Network_Security_Allow_PKU2U_authentication_requests_to_this_computer_to_use_online_identities + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_network_security_allow_pku2u_authentication_requests_to_this_computer_to_use_online_identities) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Network_Security_Allow_PKU2U_authentication_requests_to_this_computer_to_use_online_identities" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Network_security_Configure_encryption_types_allowed_for_Kerberos + # Type: string[] + # IsMandatory: False + # Values: ["DES_CBC_CRC", "DES_CBC_MD5", "RC4_HMAC_MD5", "AES128_HMAC_SHA1", "AES256_HMAC_SHA1"] + newparam(:dsc_network_security_configure_encryption_types_allowed_for_kerberos, :array_matching => :all) do + def mof_type; 'string[]' end + def mof_is_embedded?; false end + desc "Network_security_Configure_encryption_types_allowed_for_Kerberos - Valid values are DES_CBC_CRC, DES_CBC_MD5, RC4_HMAC_MD5, AES128_HMAC_SHA1, AES256_HMAC_SHA1." + validate do |value| + unless value.kind_of?(Array) || value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string or an array of strings") + end + if value.kind_of?(Array) + unless (['DES_CBC_CRC', 'des_cbc_crc', 'DES_CBC_MD5', 'des_cbc_md5', 'RC4_HMAC_MD5', 'rc4_hmac_md5', 'AES128_HMAC_SHA1', 'aes128_hmac_sha1', 'AES256_HMAC_SHA1', 'aes256_hmac_sha1'] & value).count == value.count + fail("Invalid value #{value}. Valid values are DES_CBC_CRC, DES_CBC_MD5, RC4_HMAC_MD5, AES128_HMAC_SHA1, AES256_HMAC_SHA1") + end + end + if value.kind_of?(String) + unless ['DES_CBC_CRC', 'des_cbc_crc', 'DES_CBC_MD5', 'des_cbc_md5', 'RC4_HMAC_MD5', 'rc4_hmac_md5', 'AES128_HMAC_SHA1', 'aes128_hmac_sha1', 'AES256_HMAC_SHA1', 'aes256_hmac_sha1'].include?(value) + fail("Invalid value #{value}. Valid values are DES_CBC_CRC, DES_CBC_MD5, RC4_HMAC_MD5, AES128_HMAC_SHA1, AES256_HMAC_SHA1") + end + end + end + munge do |value| + Array(value) + end + end + + # Name: Network_security_Do_not_store_LAN_Manager_hash_value_on_next_password_change + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_network_security_do_not_store_lan_manager_hash_value_on_next_password_change) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Network_security_Do_not_store_LAN_Manager_hash_value_on_next_password_change" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Network_security_Force_logoff_when_logon_hours_expire + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_network_security_force_logoff_when_logon_hours_expire) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Network_security_Force_logoff_when_logon_hours_expire" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Network_security_LAN_Manager_authentication_level + # Type: string + # IsMandatory: False + # Values: ["Send LM & NTLM responses", "Send LM & NTLM - use NTLMv2 session security if negotiated", "Send NTLM responses only", "Send NTLMv2 responses only", "Send NTLMv2 responses only. Refuse LM", "Send NTLMv2 responses only. Refuse LM & NTLM"] + newparam(:dsc_network_security_lan_manager_authentication_level) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Network_security_LAN_Manager_authentication_level - Valid values are Send LM & NTLM responses, Send LM & NTLM - use NTLMv2 session security if negotiated, Send NTLM responses only, Send NTLMv2 responses only, Send NTLMv2 responses only. Refuse LM, Send NTLMv2 responses only. Refuse LM & NTLM." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + unless ['Send LM & NTLM responses', 'send lm & ntlm responses', 'Send LM & NTLM - use NTLMv2 session security if negotiated', 'send lm & ntlm - use ntlmv2 session security if negotiated', 'Send NTLM responses only', 'send ntlm responses only', 'Send NTLMv2 responses only', 'send ntlmv2 responses only', 'Send NTLMv2 responses only. Refuse LM', 'send ntlmv2 responses only. refuse lm', 'Send NTLMv2 responses only. Refuse LM & NTLM', 'send ntlmv2 responses only. refuse lm & ntlm'].include?(value) + fail("Invalid value '#{value}'. Valid values are Send LM & NTLM responses, Send LM & NTLM - use NTLMv2 session security if negotiated, Send NTLM responses only, Send NTLMv2 responses only, Send NTLMv2 responses only. Refuse LM, Send NTLMv2 responses only. Refuse LM & NTLM") + end + end + end + + # Name: Network_security_LDAP_client_signing_requirements + # Type: string + # IsMandatory: False + # Values: ["None", "Negotiate Signing", "Require Signing"] + newparam(:dsc_network_security_ldap_client_signing_requirements) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Network_security_LDAP_client_signing_requirements - Valid values are None, Negotiate Signing, Require Signing." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + unless ['None', 'none', 'Negotiate Signing', 'negotiate signing', 'Require Signing', 'require signing'].include?(value) + fail("Invalid value '#{value}'. Valid values are None, Negotiate Signing, Require Signing") + end + end + end + + # Name: Network_security_Minimum_session_security_for_NTLM_SSP_based_including_secure_RPC_clients + # Type: string + # IsMandatory: False + # Values: ["Require NTLMv2 session security", "Require 128-bit encryption", "Both options checked"] + newparam(:dsc_network_security_minimum_session_security_for_ntlm_ssp_based_including_secure_rpc_clients) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Network_security_Minimum_session_security_for_NTLM_SSP_based_including_secure_RPC_clients - Valid values are Require NTLMv2 session security, Require 128-bit encryption, Both options checked." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + unless ['Require NTLMv2 session security', 'require ntlmv2 session security', 'Require 128-bit encryption', 'require 128-bit encryption', 'Both options checked', 'both options checked'].include?(value) + fail("Invalid value '#{value}'. Valid values are Require NTLMv2 session security, Require 128-bit encryption, Both options checked") + end + end + end + + # Name: Network_security_Minimum_session_security_for_NTLM_SSP_based_including_secure_RPC_servers + # Type: string + # IsMandatory: False + # Values: ["Require NTLMv2 session security", "Require 128-bit encryption", "Both options checked"] + newparam(:dsc_network_security_minimum_session_security_for_ntlm_ssp_based_including_secure_rpc_servers) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Network_security_Minimum_session_security_for_NTLM_SSP_based_including_secure_RPC_servers - Valid values are Require NTLMv2 session security, Require 128-bit encryption, Both options checked." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + unless ['Require NTLMv2 session security', 'require ntlmv2 session security', 'Require 128-bit encryption', 'require 128-bit encryption', 'Both options checked', 'both options checked'].include?(value) + fail("Invalid value '#{value}'. Valid values are Require NTLMv2 session security, Require 128-bit encryption, Both options checked") + end + end + end + + # Name: Network_security_Restrict_NTLM_Add_remote_server_exceptions_for_NTLM_authentication + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_network_security_restrict_ntlm_add_remote_server_exceptions_for_ntlm_authentication) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Network_security_Restrict_NTLM_Add_remote_server_exceptions_for_NTLM_authentication" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Network_security_Restrict_NTLM_Add_server_exceptions_in_this_domain + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_network_security_restrict_ntlm_add_server_exceptions_in_this_domain) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Network_security_Restrict_NTLM_Add_server_exceptions_in_this_domain" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Network_Security_Restrict_NTLM_Incoming_NTLM_Traffic + # Type: string + # IsMandatory: False + # Values: ["Disabled", "Enable auditing for domain accounts", "Enable auditing for all accounts"] + newparam(:dsc_network_security_restrict_ntlm_incoming_ntlm_traffic) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Network_Security_Restrict_NTLM_Incoming_NTLM_Traffic - Valid values are Disabled, Enable auditing for domain accounts, Enable auditing for all accounts." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + unless ['Disabled', 'disabled', 'Enable auditing for domain accounts', 'enable auditing for domain accounts', 'Enable auditing for all accounts', 'enable auditing for all accounts'].include?(value) + fail("Invalid value '#{value}'. Valid values are Disabled, Enable auditing for domain accounts, Enable auditing for all accounts") + end + end + end + + # Name: Network_Security_Restrict_NTLM_NTLM_authentication_in_this_domain + # Type: string + # IsMandatory: False + # Values: ["Disable", "Enable for domain accounts to domain servers", "Enable for domain accounts", "Enable for domain servers", "Enable all"] + newparam(:dsc_network_security_restrict_ntlm_ntlm_authentication_in_this_domain) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Network_Security_Restrict_NTLM_NTLM_authentication_in_this_domain - Valid values are Disable, Enable for domain accounts to domain servers, Enable for domain accounts, Enable for domain servers, Enable all." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + unless ['Disable', 'disable', 'Enable for domain accounts to domain servers', 'enable for domain accounts to domain servers', 'Enable for domain accounts', 'enable for domain accounts', 'Enable for domain servers', 'enable for domain servers', 'Enable all', 'enable all'].include?(value) + fail("Invalid value '#{value}'. Valid values are Disable, Enable for domain accounts to domain servers, Enable for domain accounts, Enable for domain servers, Enable all") + end + end + end + + # Name: Network_Security_Restrict_NTLM_Outgoing_NTLM_traffic_to_remote_servers + # Type: string + # IsMandatory: False + # Values: ["Allow all", "Deny all domain accounts", "Deny all accounts"] + newparam(:dsc_network_security_restrict_ntlm_outgoing_ntlm_traffic_to_remote_servers) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Network_Security_Restrict_NTLM_Outgoing_NTLM_traffic_to_remote_servers - Valid values are Allow all, Deny all domain accounts, Deny all accounts." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + unless ['Allow all', 'allow all', 'Deny all domain accounts', 'deny all domain accounts', 'Deny all accounts', 'deny all accounts'].include?(value) + fail("Invalid value '#{value}'. Valid values are Allow all, Deny all domain accounts, Deny all accounts") + end + end + end + + # Name: Network_Security_Restrict_NTLM_Audit_Incoming_NTLM_Traffic + # Type: string + # IsMandatory: False + # Values: ["Disable", "Deny for domain accounts to domain servers", "Deny for domain accounts", "Deny for domain servers", "Deny all"] + newparam(:dsc_network_security_restrict_ntlm_audit_incoming_ntlm_traffic) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Network_Security_Restrict_NTLM_Audit_Incoming_NTLM_Traffic - Valid values are Disable, Deny for domain accounts to domain servers, Deny for domain accounts, Deny for domain servers, Deny all." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + unless ['Disable', 'disable', 'Deny for domain accounts to domain servers', 'deny for domain accounts to domain servers', 'Deny for domain accounts', 'deny for domain accounts', 'Deny for domain servers', 'deny for domain servers', 'Deny all', 'deny all'].include?(value) + fail("Invalid value '#{value}'. Valid values are Disable, Deny for domain accounts to domain servers, Deny for domain accounts, Deny for domain servers, Deny all") + end + end + end + + # Name: Network_Security_Restrict_NTLM_Audit_NTLM_authentication_in_this_domain + # Type: string + # IsMandatory: False + # Values: ["Allow all", "Audit all", "Deny all"] + newparam(:dsc_network_security_restrict_ntlm_audit_ntlm_authentication_in_this_domain) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Network_Security_Restrict_NTLM_Audit_NTLM_authentication_in_this_domain - Valid values are Allow all, Audit all, Deny all." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + unless ['Allow all', 'allow all', 'Audit all', 'audit all', 'Deny all', 'deny all'].include?(value) + fail("Invalid value '#{value}'. Valid values are Allow all, Audit all, Deny all") + end + end + end + + # Name: Recovery_console_Allow_automatic_administrative_logon + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_recovery_console_allow_automatic_administrative_logon) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Recovery_console_Allow_automatic_administrative_logon" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Recovery_console_Allow_floppy_copy_and_access_to_all_drives_and_folders + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_recovery_console_allow_floppy_copy_and_access_to_all_drives_and_folders) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Recovery_console_Allow_floppy_copy_and_access_to_all_drives_and_folders" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Shutdown_Allow_system_to_be_shut_down_without_having_to_log_on + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_shutdown_allow_system_to_be_shut_down_without_having_to_log_on) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Shutdown_Allow_system_to_be_shut_down_without_having_to_log_on" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: Shutdown_Clear_virtual_memory_pagefile + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_shutdown_clear_virtual_memory_pagefile) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "Shutdown_Clear_virtual_memory_pagefile" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: System_cryptography_Force_strong_key_protection_for_user_keys_stored_on_the_computer + # Type: string + # IsMandatory: False + # Values: ["User input is not required when new keys are stored and used", "User is prompted when the key is first used", "User must enter a password each time they use a key"] + newparam(:dsc_system_cryptography_force_strong_key_protection_for_user_keys_stored_on_the_computer) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "System_cryptography_Force_strong_key_protection_for_user_keys_stored_on_the_computer - Valid values are User input is not required when new keys are stored and used, User is prompted when the key is first used, User must enter a password each time they use a key." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + unless ['User input is not required when new keys are stored and used', 'user input is not required when new keys are stored and used', 'User is prompted when the key is first used', 'user is prompted when the key is first used', 'User must enter a password each time they use a key', 'user must enter a password each time they use a key'].include?(value) + fail("Invalid value '#{value}'. Valid values are User input is not required when new keys are stored and used, User is prompted when the key is first used, User must enter a password each time they use a key") + end + end + end + + # Name: System_cryptography_Use_FIPS_compliant_algorithms_for_encryption_hashing_and_signing + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_system_cryptography_use_fips_compliant_algorithms_for_encryption_hashing_and_signing) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "System_cryptography_Use_FIPS_compliant_algorithms_for_encryption_hashing_and_signing" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: System_objects_Require_case_insensitivity_for_non_Windows_subsystems + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_system_objects_require_case_insensitivity_for_non_windows_subsystems) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "System_objects_Require_case_insensitivity_for_non_Windows_subsystems" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: System_objects_Strengthen_default_permissions_of_internal_system_objects_eg_Symbolic_Links + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_system_objects_strengthen_default_permissions_of_internal_system_objects_eg_symbolic_links) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "System_objects_Strengthen_default_permissions_of_internal_system_objects_eg_Symbolic_Links" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: System_settings_Optional_subsystems + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_system_settings_optional_subsystems) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "System_settings_Optional_subsystems" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: System_settings_Use_Certificate_Rules_on_Windows_Executables_for_Software_Restriction_Policies + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_system_settings_use_certificate_rules_on_windows_executables_for_software_restriction_policies) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "System_settings_Use_Certificate_Rules_on_Windows_Executables_for_Software_Restriction_Policies" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: User_Account_Control_Admin_Approval_Mode_for_the_Built_in_Administrator_account + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_user_account_control_admin_approval_mode_for_the_built_in_administrator_account) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "User_Account_Control_Admin_Approval_Mode_for_the_Built_in_Administrator_account" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: User_Account_Control_Allow_UIAccess_applications_to_prompt_for_elevation_without_using_the_secure_desktop + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_user_account_control_allow_uiaccess_applications_to_prompt_for_elevation_without_using_the_secure_desktop) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "User_Account_Control_Allow_UIAccess_applications_to_prompt_for_elevation_without_using_the_secure_desktop" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: User_Account_Control_Behavior_of_the_elevation_prompt_for_administrators_in_Admin_Approval_Mode + # Type: string + # IsMandatory: False + # Values: ["Elevate without prompting", "Prompt for credentials on the secure desktop", "Prompt for consent on the secure desktop", "Prompt for credentials", "Prompt for consent", "Prompt for consent for non-Windows binaries"] + newparam(:dsc_user_account_control_behavior_of_the_elevation_prompt_for_administrators_in_admin_approval_mode) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "User_Account_Control_Behavior_of_the_elevation_prompt_for_administrators_in_Admin_Approval_Mode - Valid values are Elevate without prompting, Prompt for credentials on the secure desktop, Prompt for consent on the secure desktop, Prompt for credentials, Prompt for consent, Prompt for consent for non-Windows binaries." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + unless ['Elevate without prompting', 'elevate without prompting', 'Prompt for credentials on the secure desktop', 'prompt for credentials on the secure desktop', 'Prompt for consent on the secure desktop', 'prompt for consent on the secure desktop', 'Prompt for credentials', 'prompt for credentials', 'Prompt for consent', 'prompt for consent', 'Prompt for consent for non-Windows binaries', 'prompt for consent for non-windows binaries'].include?(value) + fail("Invalid value '#{value}'. Valid values are Elevate without prompting, Prompt for credentials on the secure desktop, Prompt for consent on the secure desktop, Prompt for credentials, Prompt for consent, Prompt for consent for non-Windows binaries") + end + end + end + + # Name: User_Account_Control_Behavior_of_the_elevation_prompt_for_standard_users + # Type: string + # IsMandatory: False + # Values: ["Automatically deny elevation request", "Prompt for credentials on the secure desktop", "Prompt for crendentials"] + newparam(:dsc_user_account_control_behavior_of_the_elevation_prompt_for_standard_users) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "User_Account_Control_Behavior_of_the_elevation_prompt_for_standard_users - Valid values are Automatically deny elevation request, Prompt for credentials on the secure desktop, Prompt for crendentials." + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + unless ['Automatically deny elevation request', 'automatically deny elevation request', 'Prompt for credentials on the secure desktop', 'prompt for credentials on the secure desktop', 'Prompt for crendentials', 'prompt for crendentials'].include?(value) + fail("Invalid value '#{value}'. Valid values are Automatically deny elevation request, Prompt for credentials on the secure desktop, Prompt for crendentials") + end + end + end + + # Name: User_Account_Control_Detect_application_installations_and_prompt_for_elevation + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_user_account_control_detect_application_installations_and_prompt_for_elevation) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "User_Account_Control_Detect_application_installations_and_prompt_for_elevation" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: User_Account_Control_Only_elevate_executables_that_are_signed_and_validated + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_user_account_control_only_elevate_executables_that_are_signed_and_validated) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "User_Account_Control_Only_elevate_executables_that_are_signed_and_validated" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: User_Account_Control_Only_elevate_UIAccess_applications_that_are_installed_in_secure_locations + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_user_account_control_only_elevate_uiaccess_applications_that_are_installed_in_secure_locations) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "User_Account_Control_Only_elevate_UIAccess_applications_that_are_installed_in_secure_locations" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: User_Account_Control_Run_all_administrators_in_Admin_Approval_Mode + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_user_account_control_run_all_administrators_in_admin_approval_mode) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "User_Account_Control_Run_all_administrators_in_Admin_Approval_Mode" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: User_Account_Control_Switch_to_the_secure_desktop_when_prompting_for_elevation + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_user_account_control_switch_to_the_secure_desktop_when_prompting_for_elevation) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "User_Account_Control_Switch_to_the_secure_desktop_when_prompting_for_elevation" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + # Name: User_Account_Control_Virtualize_file_and_registry_write_failures_to_per_user_locations + # Type: string + # IsMandatory: False + # Values: None + newparam(:dsc_user_account_control_virtualize_file_and_registry_write_failures_to_per_user_locations) do + def mof_type; 'string' end + def mof_is_embedded?; false end + desc "User_Account_Control_Virtualize_file_and_registry_write_failures_to_per_user_locations" + validate do |value| + unless value.kind_of?(String) + fail("Invalid value '#{value}'. Should be a string") + end + end + end + + + def builddepends + pending_relations = super() + PuppetX::Dsc::TypeHelpers.ensure_reboot_relationship(self, pending_relations) + end +end + +Puppet::Type.type(:dsc_securityoption).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do + confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) + defaultfor :operatingsystem => :windows + + mk_resource_methods +end diff --git a/lib/puppet/type/dsc_securitysetting.rb b/lib/puppet/type/dsc_securitysetting.rb deleted file mode 100644 index 28992797b..000000000 --- a/lib/puppet/type/dsc_securitysetting.rb +++ /dev/null @@ -1,462 +0,0 @@ -require 'pathname' - -Puppet::Type.newtype(:dsc_securitysetting) do - require Pathname.new(__FILE__).dirname + '../../' + 'puppet/type/base_dsc' - require Pathname.new(__FILE__).dirname + '../../puppet_x/puppetlabs/dsc_type_helpers' - - - @doc = %q{ - The DSC SecuritySetting resource type. - Automatically generated from - 'SecurityPolicyDsc/DSCResources/MSFT_SecuritySetting/MSFT_SecuritySetting.schema.mof' - - To learn more about PowerShell Desired State Configuration, please - visit https://technet.microsoft.com/en-us/library/dn249912.aspx. - - For more information about built-in DSC Resources, please visit - https://technet.microsoft.com/en-us/library/dn249921.aspx. - - For more information about xDsc Resources, please visit - https://github.com/PowerShell/DscResources. - } - - validate do - fail('dsc_name is a required attribute') if self[:dsc_name].nil? - end - - def dscmeta_resource_friendly_name; 'SecuritySetting' end - def dscmeta_resource_name; 'MSFT_SecuritySetting' end - def dscmeta_module_name; 'SecurityPolicyDsc' end - def dscmeta_module_version; '1.5.0.0' end - - newparam(:name, :namevar => true ) do - end - - ensurable do - newvalue(:exists?) { provider.exists? } - newvalue(:present) { provider.create } - newvalue(:absent) { provider.destroy } - defaultto { :present } - end - - # Name: PsDscRunAsCredential - # Type: MSFT_Credential - # IsMandatory: False - # Values: None - newparam(:dsc_psdscrunascredential) do - def mof_type; 'MSFT_Credential' end - def mof_is_embedded?; true end - desc "PsDscRunAsCredential" - validate do |value| - unless value.kind_of?(Hash) - fail("Invalid value '#{value}'. Should be a hash") - end - PuppetX::Dsc::TypeHelpers.validate_MSFT_Credential("Credential", value) - end - end - - # Name: Name - # Type: string - # IsMandatory: True - # Values: ["MinimumPasswordAge", "MaximumPasswordAge", "MinimumPasswordLength", "PasswordComplexity", "PasswordHistorySize", "LockoutBadCount", "ForceLogoffWhenHourExpire", "NewAdministratorName", "NewGuestName", "ClearTextPassword", "LSAAnonymousNameLookup", "EnableAdminAccount", "EnableGuestAccount", "ResetLockoutCount", "LockoutDuration", "MaxServiceAge", "MaxTicketAge", "MaxRenewAge", "MaxClockSkew", "TicketValidateClient"] - newparam(:dsc_name) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "Name - This is just here to avoid conflicts Valid values are MinimumPasswordAge, MaximumPasswordAge, MinimumPasswordLength, PasswordComplexity, PasswordHistorySize, LockoutBadCount, ForceLogoffWhenHourExpire, NewAdministratorName, NewGuestName, ClearTextPassword, LSAAnonymousNameLookup, EnableAdminAccount, EnableGuestAccount, ResetLockoutCount, LockoutDuration, MaxServiceAge, MaxTicketAge, MaxRenewAge, MaxClockSkew, TicketValidateClient." - isrequired - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - unless ['MinimumPasswordAge', 'minimumpasswordage', 'MaximumPasswordAge', 'maximumpasswordage', 'MinimumPasswordLength', 'minimumpasswordlength', 'PasswordComplexity', 'passwordcomplexity', 'PasswordHistorySize', 'passwordhistorysize', 'LockoutBadCount', 'lockoutbadcount', 'ForceLogoffWhenHourExpire', 'forcelogoffwhenhourexpire', 'NewAdministratorName', 'newadministratorname', 'NewGuestName', 'newguestname', 'ClearTextPassword', 'cleartextpassword', 'LSAAnonymousNameLookup', 'lsaanonymousnamelookup', 'EnableAdminAccount', 'enableadminaccount', 'EnableGuestAccount', 'enableguestaccount', 'ResetLockoutCount', 'resetlockoutcount', 'LockoutDuration', 'lockoutduration', 'MaxServiceAge', 'maxserviceage', 'MaxTicketAge', 'maxticketage', 'MaxRenewAge', 'maxrenewage', 'MaxClockSkew', 'maxclockskew', 'TicketValidateClient', 'ticketvalidateclient'].include?(value) - fail("Invalid value '#{value}'. Valid values are MinimumPasswordAge, MaximumPasswordAge, MinimumPasswordLength, PasswordComplexity, PasswordHistorySize, LockoutBadCount, ForceLogoffWhenHourExpire, NewAdministratorName, NewGuestName, ClearTextPassword, LSAAnonymousNameLookup, EnableAdminAccount, EnableGuestAccount, ResetLockoutCount, LockoutDuration, MaxServiceAge, MaxTicketAge, MaxRenewAge, MaxClockSkew, TicketValidateClient") - end - end - end - - # Name: Ensure - # Type: string - # IsMandatory: False - # Values: ["Present", "Absent"] - newparam(:dsc_ensure) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "Ensure - Desired state of resource. Valid values are Present, Absent." - validate do |value| - resource[:ensure] = value.downcase - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - unless ['Present', 'present', 'Absent', 'absent'].include?(value) - fail("Invalid value '#{value}'. Valid values are Present, Absent") - end - end - end - - # Name: MinimumPasswordAge - # Type: sint16 - # IsMandatory: False - # Values: None - newparam(:dsc_minimumpasswordage) do - def mof_type; 'sint16' end - def mof_is_embedded?; false end - desc "MinimumPasswordAge" - validate do |value| - unless value.kind_of?(Numeric) || value.to_i.to_s == value - fail("Invalid value #{value}. Should be a signed Integer") - end - end - munge do |value| - PuppetX::Dsc::TypeHelpers.munge_integer(value) - end - end - - # Name: MaximumPasswordAge - # Type: uint16 - # IsMandatory: False - # Values: None - newparam(:dsc_maximumpasswordage) do - def mof_type; 'uint16' end - def mof_is_embedded?; false end - desc "MaximumPasswordAge" - validate do |value| - unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) - fail("Invalid value #{value}. Should be a unsigned Integer") - end - end - munge do |value| - PuppetX::Dsc::TypeHelpers.munge_integer(value) - end - end - - # Name: MinimumPasswordLength - # Type: uint16 - # IsMandatory: False - # Values: None - newparam(:dsc_minimumpasswordlength) do - def mof_type; 'uint16' end - def mof_is_embedded?; false end - desc "MinimumPasswordLength" - validate do |value| - unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) - fail("Invalid value #{value}. Should be a unsigned Integer") - end - end - munge do |value| - PuppetX::Dsc::TypeHelpers.munge_integer(value) - end - end - - # Name: PasswordComplexity - # Type: uint16 - # IsMandatory: False - # Values: None - newparam(:dsc_passwordcomplexity) do - def mof_type; 'uint16' end - def mof_is_embedded?; false end - desc "PasswordComplexity" - validate do |value| - unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) - fail("Invalid value #{value}. Should be a unsigned Integer") - end - end - munge do |value| - PuppetX::Dsc::TypeHelpers.munge_integer(value) - end - end - - # Name: PasswordHistorySize - # Type: uint16 - # IsMandatory: False - # Values: None - newparam(:dsc_passwordhistorysize) do - def mof_type; 'uint16' end - def mof_is_embedded?; false end - desc "PasswordHistorySize" - validate do |value| - unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) - fail("Invalid value #{value}. Should be a unsigned Integer") - end - end - munge do |value| - PuppetX::Dsc::TypeHelpers.munge_integer(value) - end - end - - # Name: LockoutBadCount - # Type: uint16 - # IsMandatory: False - # Values: None - newparam(:dsc_lockoutbadcount) do - def mof_type; 'uint16' end - def mof_is_embedded?; false end - desc "LockoutBadCount" - validate do |value| - unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) - fail("Invalid value #{value}. Should be a unsigned Integer") - end - end - munge do |value| - PuppetX::Dsc::TypeHelpers.munge_integer(value) - end - end - - # Name: ForceLogoffWhenHourExpire - # Type: uint16 - # IsMandatory: False - # Values: None - newparam(:dsc_forcelogoffwhenhourexpire) do - def mof_type; 'uint16' end - def mof_is_embedded?; false end - desc "ForceLogoffWhenHourExpire" - validate do |value| - unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) - fail("Invalid value #{value}. Should be a unsigned Integer") - end - end - munge do |value| - PuppetX::Dsc::TypeHelpers.munge_integer(value) - end - end - - # Name: NewAdministratorName - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_newadministratorname) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "NewAdministratorName" - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: NewGuestName - # Type: string - # IsMandatory: False - # Values: None - newparam(:dsc_newguestname) do - def mof_type; 'string' end - def mof_is_embedded?; false end - desc "NewGuestName" - validate do |value| - unless value.kind_of?(String) - fail("Invalid value '#{value}'. Should be a string") - end - end - end - - # Name: ClearTextPassword - # Type: uint16 - # IsMandatory: False - # Values: None - newparam(:dsc_cleartextpassword) do - def mof_type; 'uint16' end - def mof_is_embedded?; false end - desc "ClearTextPassword" - validate do |value| - unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) - fail("Invalid value #{value}. Should be a unsigned Integer") - end - end - munge do |value| - PuppetX::Dsc::TypeHelpers.munge_integer(value) - end - end - - # Name: LSAAnonymousNameLookup - # Type: uint16 - # IsMandatory: False - # Values: None - newparam(:dsc_lsaanonymousnamelookup) do - def mof_type; 'uint16' end - def mof_is_embedded?; false end - desc "LSAAnonymousNameLookup" - validate do |value| - unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) - fail("Invalid value #{value}. Should be a unsigned Integer") - end - end - munge do |value| - PuppetX::Dsc::TypeHelpers.munge_integer(value) - end - end - - # Name: EnableAdminAccount - # Type: uint16 - # IsMandatory: False - # Values: None - newparam(:dsc_enableadminaccount) do - def mof_type; 'uint16' end - def mof_is_embedded?; false end - desc "EnableAdminAccount" - validate do |value| - unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) - fail("Invalid value #{value}. Should be a unsigned Integer") - end - end - munge do |value| - PuppetX::Dsc::TypeHelpers.munge_integer(value) - end - end - - # Name: EnableGuestAccount - # Type: uint16 - # IsMandatory: False - # Values: None - newparam(:dsc_enableguestaccount) do - def mof_type; 'uint16' end - def mof_is_embedded?; false end - desc "EnableGuestAccount" - validate do |value| - unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) - fail("Invalid value #{value}. Should be a unsigned Integer") - end - end - munge do |value| - PuppetX::Dsc::TypeHelpers.munge_integer(value) - end - end - - # Name: ResetLockoutCount - # Type: sint16 - # IsMandatory: False - # Values: None - newparam(:dsc_resetlockoutcount) do - def mof_type; 'sint16' end - def mof_is_embedded?; false end - desc "ResetLockoutCount" - validate do |value| - unless value.kind_of?(Numeric) || value.to_i.to_s == value - fail("Invalid value #{value}. Should be a signed Integer") - end - end - munge do |value| - PuppetX::Dsc::TypeHelpers.munge_integer(value) - end - end - - # Name: LockoutDuration - # Type: sint16 - # IsMandatory: False - # Values: None - newparam(:dsc_lockoutduration) do - def mof_type; 'sint16' end - def mof_is_embedded?; false end - desc "LockoutDuration" - validate do |value| - unless value.kind_of?(Numeric) || value.to_i.to_s == value - fail("Invalid value #{value}. Should be a signed Integer") - end - end - munge do |value| - PuppetX::Dsc::TypeHelpers.munge_integer(value) - end - end - - # Name: MaxServiceAge - # Type: uint16 - # IsMandatory: False - # Values: None - newparam(:dsc_maxserviceage) do - def mof_type; 'uint16' end - def mof_is_embedded?; false end - desc "MaxServiceAge" - validate do |value| - unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) - fail("Invalid value #{value}. Should be a unsigned Integer") - end - end - munge do |value| - PuppetX::Dsc::TypeHelpers.munge_integer(value) - end - end - - # Name: MaxTicketAge - # Type: uint16 - # IsMandatory: False - # Values: None - newparam(:dsc_maxticketage) do - def mof_type; 'uint16' end - def mof_is_embedded?; false end - desc "MaxTicketAge" - validate do |value| - unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) - fail("Invalid value #{value}. Should be a unsigned Integer") - end - end - munge do |value| - PuppetX::Dsc::TypeHelpers.munge_integer(value) - end - end - - # Name: MaxRenewAge - # Type: uint16 - # IsMandatory: False - # Values: None - newparam(:dsc_maxrenewage) do - def mof_type; 'uint16' end - def mof_is_embedded?; false end - desc "MaxRenewAge" - validate do |value| - unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) - fail("Invalid value #{value}. Should be a unsigned Integer") - end - end - munge do |value| - PuppetX::Dsc::TypeHelpers.munge_integer(value) - end - end - - # Name: MaxClockSkew - # Type: uint16 - # IsMandatory: False - # Values: None - newparam(:dsc_maxclockskew) do - def mof_type; 'uint16' end - def mof_is_embedded?; false end - desc "MaxClockSkew" - validate do |value| - unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) - fail("Invalid value #{value}. Should be a unsigned Integer") - end - end - munge do |value| - PuppetX::Dsc::TypeHelpers.munge_integer(value) - end - end - - # Name: TicketValidateClient - # Type: uint16 - # IsMandatory: False - # Values: None - newparam(:dsc_ticketvalidateclient) do - def mof_type; 'uint16' end - def mof_is_embedded?; false end - desc "TicketValidateClient" - validate do |value| - unless (value.kind_of?(Numeric) && value >= 0) || (value.to_i.to_s == value && value.to_i >= 0) - fail("Invalid value #{value}. Should be a unsigned Integer") - end - end - munge do |value| - PuppetX::Dsc::TypeHelpers.munge_integer(value) - end - end - - - def builddepends - pending_relations = super() - PuppetX::Dsc::TypeHelpers.ensure_reboot_relationship(self, pending_relations) - end -end - -Puppet::Type.type(:dsc_securitysetting).provide :powershell, :parent => Puppet::Type.type(:base_dsc).provider(:powershell) do - confine :true => (Gem::Version.new(Facter.value(:powershell_version)) >= Gem::Version.new('5.0.10586.117')) - defaultfor :operatingsystem => :windows - - mk_resource_methods -end diff --git a/lib/puppet/type/dsc_securitytemplate.rb b/lib/puppet/type/dsc_securitytemplate.rb index 2e22e0f70..33fbd3d7b 100644 --- a/lib/puppet/type/dsc_securitytemplate.rb +++ b/lib/puppet/type/dsc_securitytemplate.rb @@ -27,7 +27,7 @@ def dscmeta_resource_friendly_name; 'SecurityTemplate' end def dscmeta_resource_name; 'MSFT_SecurityTemplate' end def dscmeta_module_name; 'SecurityPolicyDsc' end - def dscmeta_module_version; '1.5.0.0' end + def dscmeta_module_version; '2.2.0.0' end newparam(:name, :namevar => true ) do end diff --git a/lib/puppet/type/dsc_userrightsassignment.rb b/lib/puppet/type/dsc_userrightsassignment.rb index f98df599a..6d2d32403 100644 --- a/lib/puppet/type/dsc_userrightsassignment.rb +++ b/lib/puppet/type/dsc_userrightsassignment.rb @@ -27,7 +27,7 @@ def dscmeta_resource_friendly_name; 'UserRightsAssignment' end def dscmeta_resource_name; 'MSFT_UserRightsAssignment' end def dscmeta_module_name; 'SecurityPolicyDsc' end - def dscmeta_module_version; '1.5.0.0' end + def dscmeta_module_version; '2.2.0.0' end newparam(:name, :namevar => true ) do end diff --git a/lib/puppet_x/dsc_resources/SecurityPolicyDsc/DSCResources/MSFT_AccountPolicy/AccountPolicyData.psd1 b/lib/puppet_x/dsc_resources/SecurityPolicyDsc/DSCResources/MSFT_AccountPolicy/AccountPolicyData.psd1 new file mode 100644 index 000000000..8127c3e98 --- /dev/null +++ b/lib/puppet_x/dsc_resources/SecurityPolicyDsc/DSCResources/MSFT_AccountPolicy/AccountPolicyData.psd1 @@ -0,0 +1,117 @@ + +@{ + "Enforce_password_history" = @{ + Value = 'PasswordHistorySize' + Section = 'System Access' + Option = @{ + String = '' + } + } + + "Maximum_Password_Age" = @{ + Value = 'MaximumPasswordAge' + Section = 'System Access' + Option = @{ + String = '' + } + } + + "Minimum_Password_Age" = @{ + Value = 'MinimumPasswordAge' + Section = 'System Access' + Option = @{ + String = '' + } + } + + "Minimum_Password_Length" = @{ + Value = 'MinimumPasswordLength' + Section = 'System Access' + Option = @{ + String = '' + } + } + + "Password_must_meet_complexity_requirements" = @{ + Value = 'PasswordComplexity' + Section = 'System Access' + Option = @{ + Enabled = '1' + Disabled = '0' + } + } + + "Store_passwords_using_reversible_encryption" = @{ + Value = 'ClearTextPassword' + Section = 'System Access' + Option = @{ + Enabled = '1' + Disabled = '0' + } + } + + "Account_lockout_duration" = @{ + Value = 'LockoutDuration' + Section = 'System Access' + Option = @{ + String = '' + } + } + + "Account_lockout_threshold" = @{ + Value = 'LockoutBadCount' + Section = 'System Access' + Option = @{ + String = '' + } + } + + "Reset_account_lockout_counter_after" = @{ + Value = 'ResetLockoutCount' + Section = 'System Access' + Option = @{ + String = '' + } + } + + "Enforce_user_logon_restrictions" = @{ + Value = 'TicketValidateClient' + Section = 'Kerberos Policy' + Option = @{ + Enabled = '1' + Disabled = '0' + } + } + + "Maximum_lifetime_for_service_ticket" = @{ + Value = 'MaxServiceAge' + Section = 'Kerberos Policy' + Option = @{ + String = '' + } + } + + "Maximum_lifetime_for_user_ticket" = @{ + Value = 'MaxTicketAge' + Section = 'Kerberos Policy' + Option = @{ + String = '' + } + } + + "Maximum_lifetime_for_user_ticket_renewal" = @{ + Value = 'MaxRenewAge' + Section = 'Kerberos Policy' + Option = @{ + String = '' + } + } + + "Maximum_tolerance_for_computer_clock_synchronization" = @{ + Value = 'MaxClockSkew' + Section = 'Kerberos Policy' + Option = @{ + String = '' + } + } +} diff --git a/lib/puppet_x/dsc_resources/SecurityPolicyDsc/DSCResources/MSFT_AccountPolicy/MSFT_AccountPolicy.psm1 b/lib/puppet_x/dsc_resources/SecurityPolicyDsc/DSCResources/MSFT_AccountPolicy/MSFT_AccountPolicy.psm1 new file mode 100644 index 000000000..2de030aa8 --- /dev/null +++ b/lib/puppet_x/dsc_resources/SecurityPolicyDsc/DSCResources/MSFT_AccountPolicy/MSFT_AccountPolicy.psm1 @@ -0,0 +1,312 @@ + +Import-Module -Name (Join-Path -Path ( Split-Path $PSScriptRoot -Parent ) ` +-ChildPath 'SecurityPolicyResourceHelper\SecurityPolicyResourceHelper.psm1') ` +-Force + +$script:localizedData = Get-LocalizedData -ResourceName 'MSFT_AccountPolicy' + +<# + .SYNOPSIS + Retreives the current account policy configuration +#> +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $Name + ) + + $returnValue = @{} + $currentSecurityPolicy = Get-SecurityPolicy -Area SECURITYPOLICY + $accountPolicyData = Get-PolicyOptionData -FilePath $("$PSScriptRoot\AccountPolicyData.psd1").Normalize() + $accountPolicyList = Get-PolicyOptionList -ModuleName MSFT_AccountPolicy + + foreach ( $accountPolicy in $accountPolicyList ) + { + Write-Verbose $accountPolicy + $section = $accountPolicyData.$accountPolicy.Section + Write-Verbose -Message ( $script:localizedData.Section -f $section ) + $valueName = $accountPolicyData.$accountPolicy.Value + Write-Verbose -Message ( $script:localizedData.Value -f $valueName ) + $options = $accountPolicyData.$accountPolicy.Option + Write-Verbose -Message ( $script:localizedData.Option -f $($options -join ',') ) + $currentValue = $currentSecurityPolicy.$section.$valueName + Write-Verbose -Message ( $script:localizedData.RawValue -f $($currentValue -join ',') ) + + if ( $options.keys -eq 'String' ) + { + $stringValue = ( $currentValue -split ',' )[-1] + $resultValue = ( $stringValue -replace '"' ).Trim() + } + else + { + Write-Verbose -Message ( $script:localizedData.RetrievingValue -f $valueName ) + if ( $currentSecurityPolicy.$section.keys -contains $valueName ) + { + $resultValue = ( $accountPolicyData.$accountPolicy.Option.GetEnumerator() | + Where-Object -Property Value -eq $currentValue.Trim() ).Name + } + else + { + $resultValue = $null + } + } + $returnValue.Add( $accountPolicy, $resultValue ) + } + return $returnValue +} + + +<# + .SYNOPSIS + Sets the specified account policy +#> +function Set-TargetResource +{ + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "")] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingUserNameAndPassWordParams", "")] + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $Name, + + [Parameter()] + [System.UInt32] + $Enforce_password_history, + + [Parameter()] + [System.UInt32] + $Maximum_Password_Age, + + [Parameter()] + [System.UInt32] + $Minimum_Password_Age, + + [Parameter()] + [System.UInt32] + $Minimum_Password_Length, + + [Parameter()] + [ValidateSet("Enabled","Disabled")] + [System.String] + $Password_must_meet_complexity_requirements, + + [Parameter()] + [ValidateSet("Enabled","Disabled")] + [System.String] + $Store_passwords_using_reversible_encryption, + + [Parameter()] + [System.UInt32] + $Account_lockout_duration, + + [Parameter()] + [System.UInt32] + $Account_lockout_threshold, + + [Parameter()] + [System.UInt32] + $Reset_account_lockout_counter_after, + + [Parameter()] + [ValidateSet("Enabled","Disabled")] + [System.String] + $Enforce_user_logon_restrictions, + + [Parameter()] + [System.UInt32] + $Maximum_lifetime_for_service_ticket, + + [Parameter()] + [System.UInt32] + $Maximum_lifetime_for_user_ticket, + + [Parameter()] + [System.UInt32] + $Maximum_lifetime_for_user_ticket_renewal, + + [Parameter()] + [System.UInt32] + $Maximum_tolerance_for_computer_clock_synchronization + ) + + $kerberosPolicies = @() + $systemAccessPolicies = @() + $nonComplaintPolicies = @() + $accountPolicyList = Get-PolicyOptionList -ModuleName MSFT_AccountPolicy + $accountPolicyData = Get-PolicyOptionData -FilePath $("$PSScriptRoot\AccountPolicyData.psd1").Normalize() + $script:seceditOutput = "$env:TEMP\Secedit-OutPut.txt" + $accountPolicyToAddInf = "$env:TEMP\accountPolicyToAdd.inf" + + $desiredPolicies = $PSBoundParameters.GetEnumerator() | Where-Object -FilterScript { $PSItem.key -in $accountPolicyList } + + foreach ( $policy in $desiredPolicies ) + { + $testParameters = @{ + Name = 'Test' + $policy.Key = $policy.Value + Verbose = $false + } + + # define what policies are not in a desired state so we only add those policies + # that need to be changed to the INF + $isInDesiredState = Test-TargetResource @testParameters + if ( -not ( $isInDesiredState ) ) + { + $policyKey = $policy.Key + $policyData = $accountPolicyData.$policyKey + $nonComplaintPolicies += $policyKey + + if ( $policyData.Option.GetEnumerator().Name -eq 'String' ) + { + if ( [String]::IsNullOrWhiteSpace( $policyData.Option.String ) ) + { + $newValue = $policy.value + } + else + { + $newValue = "$($policyData.Option.String)" + "$($policy.Value)" + } + } + else + { + $newValue = $($policyData.Option[$policy.value]) + } + + if ( $policyData.Section -eq 'System Access' ) + { + $systemAccessPolicies += "$($policyData.Value)=$newValue" + } + else + { + $kerberosPolicies += "$($policyData.Value)=$newValue" + } + } + } + + $infTemplate = Add-PolicyOption -SystemAccessPolicies $systemAccessPolicies -KerberosPolicies $registryPolicies + + Out-File -InputObject $infTemplate -FilePath $accountPolicyToAddInf -Encoding unicode -Force + + Invoke-Secedit -InfPath $accountPolicyToAddInf -SecEditOutput $script:seceditOutput + Remove-Item -Path $accountPolicyToAddInf + + $successResult = Test-TargetResource @PSBoundParameters + + if ( $successResult -eq $false ) + { + throw "$($script:localizedData.SetFailed -f $($nonComplaintPolicies -join ','))" + } + else + { + Write-Verbose -Message ($script:localizedData.SetSuccess) + } +} + + +<# + .SYNOPSIS + Tests the desired account policy configuration against the current configuration +#> +function Test-TargetResource +{ + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "")] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingUserNameAndPassWordParams", "")] + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $Name, + + [Parameter()] + [System.UInt32] + $Enforce_password_history, + + [Parameter()] + [System.UInt32] + $Maximum_Password_Age, + + [Parameter()] + [System.UInt32] + $Minimum_Password_Age, + + [Parameter()] + [System.UInt32] + $Minimum_Password_Length, + + [Parameter()] + [ValidateSet("Enabled","Disabled")] + [System.String] + $Password_must_meet_complexity_requirements, + + [Parameter()] + [ValidateSet("Enabled","Disabled")] + [System.String] + $Store_passwords_using_reversible_encryption, + + [Parameter()] + [System.UInt32] + $Account_lockout_duration, + + [Parameter()] + [System.UInt32] + $Account_lockout_threshold, + + [Parameter()] + [System.UInt32] + $Reset_account_lockout_counter_after, + + [Parameter()] + [ValidateSet("Enabled","Disabled")] + [System.String] + $Enforce_user_logon_restrictions, + + [Parameter()] + [System.UInt32] + $Maximum_lifetime_for_service_ticket, + + [Parameter()] + [System.UInt32] + $Maximum_lifetime_for_user_ticket, + + [Parameter()] + [System.UInt32] + $Maximum_lifetime_for_user_ticket_renewal, + + [Parameter()] + [System.UInt32] + $Maximum_tolerance_for_computer_clock_synchronization + ) + + $currentAccountPolicies = Get-TargetResource -Name $Name -Verbose:0 + + $desiredAccountPolicies = $PSBoundParameters + + foreach ( $policy in $desiredAccountPolicies.Keys ) + { + if ( $currentAccountPolicies.ContainsKey( $policy ) ) + { + Write-Verbose -Message ( $script:localizedData.TestingPolicy -f $policy ) + Write-Verbose -Message ( $script:localizedData.PoliciesBeingCompared -f $($currentAccountPolicies[$policy] -join ',' ), $($desiredAccountPolicies[$policy] -join ',' ) ) + + if ( $currentAccountPolicies[$policy] -ne $desiredAccountPolicies[$policy] ) + { + return $false + } + } + } + + # if the code made it this far we must be in a desired state + return $true +} + +Export-ModuleMember -Function *-TargetResource + diff --git a/lib/puppet_x/dsc_resources/SecurityPolicyDsc/DSCResources/MSFT_AccountPolicy/MSFT_AccountPolicy.schema.mof b/lib/puppet_x/dsc_resources/SecurityPolicyDsc/DSCResources/MSFT_AccountPolicy/MSFT_AccountPolicy.schema.mof new file mode 100644 index 000000000..1d1b02b76 --- /dev/null +++ b/lib/puppet_x/dsc_resources/SecurityPolicyDsc/DSCResources/MSFT_AccountPolicy/MSFT_AccountPolicy.schema.mof @@ -0,0 +1,21 @@ + +[ClassVersion("1.0.0.0"), FriendlyName("AccountPolicy")] +class MSFT_AccountPolicy : OMI_BaseResource +{ + [Key, Description("A unique name of the AccountPolicy resource instance. This is not used during configuration.")] String Name; + [Write] Uint32 Enforce_password_history; + [Write] Uint32 Maximum_Password_Age; + [Write] Uint32 Minimum_Password_Age; + [Write] Uint32 Minimum_Password_Length; + [Write, ValueMap{"Enabled","Disabled"}, Values{"Enabled","Disabled"}] String Password_must_meet_complexity_requirements; + [Write, ValueMap{"Enabled","Disabled"}, Values{"Enabled","Disabled"}] String Store_passwords_using_reversible_encryption; + [Write] Uint32 Account_lockout_duration; + [Write] Uint32 Account_lockout_threshold; + [Write] Uint32 Reset_account_lockout_counter_after; + [Write, ValueMap{"Enabled","Disabled"}, Values{"Enabled","Disabled"}] String Enforce_user_logon_restrictions; + [Write] Uint32 Maximum_lifetime_for_service_ticket; + [Write] Uint32 Maximum_lifetime_for_user_ticket; + [Write] Uint32 Maximum_lifetime_for_user_ticket_renewal; + [Write] Uint32 Maximum_tolerance_for_computer_clock_synchronization; +}; + diff --git a/lib/puppet_x/dsc_resources/SecurityPolicyDsc/DSCResources/MSFT_AccountPolicy/en-US/MSFT_AccountPolicy.strings.psd1 b/lib/puppet_x/dsc_resources/SecurityPolicyDsc/DSCResources/MSFT_AccountPolicy/en-US/MSFT_AccountPolicy.strings.psd1 new file mode 100644 index 000000000..d3097274c --- /dev/null +++ b/lib/puppet_x/dsc_resources/SecurityPolicyDsc/DSCResources/MSFT_AccountPolicy/en-US/MSFT_AccountPolicy.strings.psd1 @@ -0,0 +1,11 @@ +ConvertFrom-StringData @' + Section = Section: {0} + Value = ValueName: {0} + Option = Options: {0} + RawValue = Raw current value: {0} + TestingPolicy = Testing AccountPolicy: {0} + SetFailed = Failed to update Account Policy {0}. Refer to %windir%\\security\\logs\\scesrv.log for details. + SetSuccess = Successfully update Account Policy + PoliciesBeingCompared = Current policy: {0} Desired policy: {1} + RetrievingValue = Retrieving value for {0} +'@ diff --git a/lib/puppet_x/dsc_resources/SecurityPolicyDsc/DSCResources/MSFT_SecurityOption/MSFT_SecurityOption.psm1 b/lib/puppet_x/dsc_resources/SecurityPolicyDsc/DSCResources/MSFT_SecurityOption/MSFT_SecurityOption.psm1 new file mode 100644 index 000000000..60282b31d --- /dev/null +++ b/lib/puppet_x/dsc_resources/SecurityPolicyDsc/DSCResources/MSFT_SecurityOption/MSFT_SecurityOption.psm1 @@ -0,0 +1,1185 @@ + +Import-Module -Name (Join-Path -Path ( Split-Path $PSScriptRoot -Parent ) ` + -ChildPath 'SecurityPolicyResourceHelper\SecurityPolicyResourceHelper.psm1') ` + -Force + +$script:localizedData = Get-LocalizedData -ResourceName 'MSFT_SecurityOption' + +<# + .SYNOPSIS + Returns all the Security Options that are currently configured + + .PARAMETER Name + Describes the security option to be managed. This could be anything as long as it is unique. This property is not + used during the configuration process. +#> +function Get-TargetResource +{ + [CmdletBinding()] + [OutputType([System.Collections.Hashtable])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $Name + ) + + $returnValue = @{} + $currentSecurityPolicy = Get-SecurityPolicy -Area SECURITYPOLICY + $securityOptionData = Get-PolicyOptionData -FilePath $("$PSScriptRoot\SecurityOptionData.psd1").Normalize() + $securityOptionList = Get-PolicyOptionList -ModuleName MSFT_SecurityOption + + foreach ( $securityOption in $securityOptionList ) + { + $section = $securityOptionData.$securityOption.Section + Write-Verbose -Message ( $script:localizedData.Section -f $section ) + $valueName = $securityOptionData.$securityOption.Value + Write-Verbose -Message ( $script:localizedData.Value -f $valueName ) + $options = $securityOptionData.$securityOption.Option + Write-Verbose -Message ( $script:localizedData.Option -f $($options -join ',') ) + $currentValue = $currentSecurityPolicy.$section.$valueName + Write-Verbose -Message ( $script:localizedData.RawValue -f $($currentValue -join ',') ) + + if ( $options.keys -eq 'String' ) + { + if ( $securityOption -eq 'Interactive_logon_Message_text_for_users_attempting_to_log_on' ) + { + $resultValue = ($currentValue -split '7,')[-1].Trim() + } + else + { + $stringValue = ( $currentValue -split ',' )[-1] + $resultValue = ( $stringValue -replace '"' ).Trim() + } + } + else + { + Write-Verbose -Message ( $script:localizedData.RetrievingValue -f $valueName ) + if ( $currentSecurityPolicy.$section.keys -contains $valueName ) + { + if ( $securityOption -eq "Network_security_Configure_encryption_types_allowed_for_Kerberos" ) + { + $resultValue = ConvertTo-KerberosEncryptionOption -EncryptionValue $currentValue + } + else + { + $resultValue = ($securityOptionData.$securityOption.Option.GetEnumerator() | + Where-Object -Property Value -eq $currentValue.Trim() ).Name + } + } + else + { + $resultValue = $null + } + } + $returnValue.Add( $securityOption, $resultValue ) + } + return $returnValue +} + + +<# + .SYNOPSIS + Applies the desired security option configuration. +#> +function Set-TargetResource +{ + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "")] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingUserNameAndPassWordParams", "")] + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $Name, + + [Parameter()] + [ValidateSet("Enabled", "Disabled")] + [System.String] + $Accounts_Administrator_account_status, + + [Parameter()] + [ValidateSet("This policy is disabled", "Users cant add Microsoft accounts", "Users cant add or log on with Microsoft accounts")] + [System.String] + $Accounts_Block_Microsoft_accounts, + + [Parameter()] + [ValidateSet("Enabled", "Disabled")] + [System.String] + $Accounts_Guest_account_status, + + [Parameter()] + [ValidateSet("Enabled", "Disabled")] + [System.String] + $Accounts_Limit_local_account_use_of_blank_passwords_to_console_logon_only, + + [Parameter()] + [System.String] + $Accounts_Rename_administrator_account, + + [Parameter()] + [System.String] + $Accounts_Rename_guest_account, + + [Parameter()] + [ValidateSet("Enabled", "Disabled")] + [System.String] + $Audit_Audit_the_access_of_global_system_objects, + + [Parameter()] + [ValidateSet("Enabled", "Disabled")] + [System.String] + $Audit_Audit_the_use_of_Backup_and_Restore_privilege, + + [Parameter()] + [ValidateSet("Enabled", "Disabled")] + [System.String] + $Audit_Force_audit_policy_subcategory_settings_Windows_Vista_or_later_to_override_audit_policy_category_settings, + + [Parameter()] + [ValidateSet("Enabled", "Disabled")] + [System.String] + $Audit_Shut_down_system_immediately_if_unable_to_log_security_audits, + + [Parameter()] + [System.String] + $DCOM_Machine_Access_Restrictions_in_Security_Descriptor_Definition_Language_SDDL_syntax, + + [Parameter()] + [System.String] + $DCOM_Machine_Launch_Restrictions_in_Security_Descriptor_Definition_Language_SDDL_syntax, + + [Parameter()] + [System.String] + $Devices_Allow_undock_without_having_to_log_on, + + [Parameter()] + [ValidateSet("Administrators", "Administrators and Power Users", "Administrators and Interactive Users")] + [System.String] + $Devices_Allowed_to_format_and_eject_removable_media, + + [Parameter()] + [System.String] + $Devices_Prevent_users_from_installing_printer_drivers, + + [Parameter()] + [System.String] + $Devices_Restrict_CD_ROM_access_to_locally_logged_on_user_only, + + [Parameter()] + [System.String] + $Devices_Restrict_floppy_access_to_locally_logged_on_user_only, + + [Parameter()] + [System.String] + $Domain_controller_Allow_server_operators_to_schedule_tasks, + + [Parameter()] + [System.String] + $Domain_controller_LDAP_server_signing_requirements, + + [Parameter()] + [System.String] + $Domain_controller_Refuse_machine_account_password_changes, + + [Parameter()] + [System.String] + $Domain_member_Digitally_encrypt_or_sign_secure_channel_data_always, + + [Parameter()] + [System.String] + $Domain_member_Digitally_encrypt_secure_channel_data_when_possible, + + [Parameter()] + [System.String] + $Domain_member_Digitally_sign_secure_channel_data_when_possible, + + [Parameter()] + [System.String] + $Domain_member_Disable_machine_account_password_changes, + + [Parameter()] + [System.String] + $Domain_member_Maximum_machine_account_password_age, + + [Parameter()] + [System.String] + $Domain_member_Require_strong_Windows_2000_or_later_session_key, + + [Parameter()] + [ValidateSet("User displayname, domain and user names", "User display name only", "Do not display user information")] + [System.String] + $Interactive_logon_Display_user_information_when_the_session_is_locked, + + [Parameter()] + [System.String] + $Interactive_logon_Do_not_display_last_user_name, + + [Parameter()] + [System.String] + $Interactive_logon_Do_not_require_CTRL_ALT_DEL, + + [Parameter()] + [System.String] + $Interactive_logon_Machine_account_lockout_threshold, + + [Parameter()] + [System.String] + $Interactive_logon_Machine_inactivity_limit, + + [Parameter()] + [System.String] + $Interactive_logon_Message_text_for_users_attempting_to_log_on, + + [Parameter()] + [System.String] + $Interactive_logon_Message_title_for_users_attempting_to_log_on, + + [Parameter()] + [System.String] + $Interactive_logon_Number_of_previous_logons_to_cache_in_case_domain_controller_is_not_available, + + [Parameter()] + [System.String] + $Interactive_logon_Prompt_user_to_change_password_before_expiration, + + [Parameter()] + [System.String] + $Interactive_logon_Require_Domain_Controller_authentication_to_unlock_workstation, + + [Parameter()] + [System.String] + $Interactive_logon_Require_smart_card, + + [Parameter()] + [ValidateSet("No Action", "Lock workstation", "Force logoff", "Disconnect if a remote Remote Desktop Services session")] + [System.String] + $Interactive_logon_Smart_card_removal_behavior, + + [Parameter()] + [System.String] + $Microsoft_network_client_Digitally_sign_communications_always, + + [Parameter()] + [System.String] + $Microsoft_network_client_Digitally_sign_communications_if_server_agrees, + + [Parameter()] + [System.String] + $Microsoft_network_client_Send_unencrypted_password_to_third_party_SMB_servers, + + [Parameter()] + [System.String] + $Microsoft_network_server_Amount_of_idle_time_required_before_suspending_session, + + [Parameter()] + [System.String] + $Microsoft_network_server_Attempt_S4U2Self_to_obtain_claim_information, + + [Parameter()] + [System.String] + $Microsoft_network_server_Digitally_sign_communications_always, + + [Parameter()] + [System.String] + $Microsoft_network_server_Digitally_sign_communications_if_client_agrees, + + [Parameter()] + [System.String] + $Microsoft_network_server_Disconnect_clients_when_logon_hours_expire, + + [Parameter()] + [ValidateSet("Off", "Accept if provided by the client", "Required from client")] + [System.String] + $Microsoft_network_server_Server_SPN_target_name_validation_level, + + [Parameter()] + [System.String] + $Network_access_Allow_anonymous_SID_Name_translation, + + [Parameter()] + [System.String] + $Network_access_Do_not_allow_anonymous_enumeration_of_SAM_accounts, + + [Parameter()] + [System.String] + $Network_access_Do_not_allow_anonymous_enumeration_of_SAM_accounts_and_shares, + + [Parameter()] + [System.String] + $Network_access_Do_not_allow_storage_of_passwords_and_credentials_for_network_authentication, + + [Parameter()] + [System.String] + $Network_access_Let_Everyone_permissions_apply_to_anonymous_users, + + [Parameter()] + [System.String] + $Network_access_Named_Pipes_that_can_be_accessed_anonymously, + + [Parameter()] + [System.String] + $Network_access_Remotely_accessible_registry_paths, + + [Parameter()] + [System.String] + $Network_access_Remotely_accessible_registry_paths_and_subpaths, + + [Parameter()] + [System.String] + $Network_access_Restrict_anonymous_access_to_Named_Pipes_and_Shares, + + [Parameter()] + [System.String] + $Network_access_Shares_that_can_be_accessed_anonymously, + + [Parameter()] + [ValidateSet("Classic - Local users authenticate as themselves", "Guest only - Local users authenticate as Guest")] + [System.String] + $Network_access_Sharing_and_security_model_for_local_accounts, + + [Parameter()] + [System.String] + $Network_security_Allow_Local_System_to_use_computer_identity_for_NTLM, + + [Parameter()] + [System.String] + $Network_security_Allow_LocalSystem_NULL_session_fallback, + + [Parameter()] + [System.String] + $Network_Security_Allow_PKU2U_authentication_requests_to_this_computer_to_use_online_identities, + + [Parameter()] + [ValidateSet("DES_CBC_CRC", "DES_CBC_MD5", "RC4_HMAC_MD5", "AES128_HMAC_SHA1", "AES256_HMAC_SHA1")] + [System.String[]] + $Network_security_Configure_encryption_types_allowed_for_Kerberos, + + [Parameter()] + [System.String] + $Network_security_Do_not_store_LAN_Manager_hash_value_on_next_password_change, + + [Parameter()] + [System.String] + $Network_security_Force_logoff_when_logon_hours_expire, + + [Parameter()] + [ValidateSet("Send LM & NTLM responses", "Send LM & NTLM - use NTLMv2 session security if negotiated", "Send NTLM responses only", "Send NTLMv2 responses only", "Send NTLMv2 responses only. Refuse LM", "Send NTLMv2 responses only. Refuse LM & NTLM")] + [System.String] + $Network_security_LAN_Manager_authentication_level, + + [Parameter()] + [ValidateSet("None", "Negotiate Signing", "Require Signing")] + [System.String] + $Network_security_LDAP_client_signing_requirements, + + [Parameter()] + [ValidateSet("Require NTLMv2 session security", "Require 128-bit encryption", "Both options checked")] + [System.String] + $Network_security_Minimum_session_security_for_NTLM_SSP_based_including_secure_RPC_clients, + + [Parameter()] + [ValidateSet("Require NTLMv2 session security", "Require 128-bit encryption", "Both options checked")] + [System.String] + $Network_security_Minimum_session_security_for_NTLM_SSP_based_including_secure_RPC_servers, + + [Parameter()] + [System.String] + $Network_security_Restrict_NTLM_Add_remote_server_exceptions_for_NTLM_authentication, + + [Parameter()] + [System.String] + $Network_security_Restrict_NTLM_Add_server_exceptions_in_this_domain, + + [Parameter()] + [ValidateSet("Disabled", "Enable auditing for domain accounts", "Enable auditing for all accounts")] + [System.String] + $Network_Security_Restrict_NTLM_Incoming_NTLM_Traffic, + + [Parameter()] + [ValidateSet("Disable", "Enable for domain accounts to domain servers", "Enable for domain accounts", "Enable for domain servers", "Enable all")] + [System.String] + $Network_Security_Restrict_NTLM_NTLM_authentication_in_this_domain, + + [Parameter()] + [ValidateSet("Allow all", "Deny all domain accounts", "Deny all accounts")] + [System.String] + $Network_Security_Restrict_NTLM_Outgoing_NTLM_traffic_to_remote_servers, + + [Parameter()] + [ValidateSet("Disable", "Deny for domain accounts to domain servers", "Deny for domain accounts", "Deny for domain servers", "Deny all")] + [System.String] + $Network_Security_Restrict_NTLM_Audit_Incoming_NTLM_Traffic, + + [Parameter()] + [ValidateSet("Allow all", "Audit all", "Deny all")] + [System.String] + $Network_Security_Restrict_NTLM_Audit_NTLM_authentication_in_this_domain, + + [Parameter()] + [System.String] + $Recovery_console_Allow_automatic_administrative_logon, + + [Parameter()] + [System.String] + $Recovery_console_Allow_floppy_copy_and_access_to_all_drives_and_folders, + + [Parameter()] + [System.String] + $Shutdown_Allow_system_to_be_shut_down_without_having_to_log_on, + + [Parameter()] + [System.String] + $Shutdown_Clear_virtual_memory_pagefile, + + [Parameter()] + [ValidateSet("User input is not required when new keys are stored and used", "User is prompted when the key is first used", "User must enter a password each time they use a key")] + [System.String] + $System_cryptography_Force_strong_key_protection_for_user_keys_stored_on_the_computer, + + [Parameter()] + [System.String] + $System_cryptography_Use_FIPS_compliant_algorithms_for_encryption_hashing_and_signing, + + [Parameter()] + [System.String] + $System_objects_Require_case_insensitivity_for_non_Windows_subsystems, + + [Parameter()] + [System.String] + $System_objects_Strengthen_default_permissions_of_internal_system_objects_eg_Symbolic_Links, + + [Parameter()] + [System.String] + $System_settings_Optional_subsystems, + + [Parameter()] + [System.String] + $System_settings_Use_Certificate_Rules_on_Windows_Executables_for_Software_Restriction_Policies, + + [Parameter()] + [System.String] + $User_Account_Control_Admin_Approval_Mode_for_the_Built_in_Administrator_account, + + [Parameter()] + [System.String] + $User_Account_Control_Allow_UIAccess_applications_to_prompt_for_elevation_without_using_the_secure_desktop, + + [Parameter()] + [ValidateSet("Elevate without prompting", "Prompt for credentials on the secure desktop", "Prompt for consent on the secure desktop", "Prompt for credentials", "Prompt for consent", "Prompt for consent for non-Windows binaries")] + [System.String] + $User_Account_Control_Behavior_of_the_elevation_prompt_for_administrators_in_Admin_Approval_Mode, + + [Parameter()] + [ValidateSet("Automatically deny elevation request", "Prompt for credentials on the secure desktop", "Prompt for crendentials")] + [System.String] + $User_Account_Control_Behavior_of_the_elevation_prompt_for_standard_users, + + [Parameter()] + [System.String] + $User_Account_Control_Detect_application_installations_and_prompt_for_elevation, + + [Parameter()] + [System.String] + $User_Account_Control_Only_elevate_executables_that_are_signed_and_validated, + + [Parameter()] + [System.String] + $User_Account_Control_Only_elevate_UIAccess_applications_that_are_installed_in_secure_locations, + + [Parameter()] + [System.String] + $User_Account_Control_Run_all_administrators_in_Admin_Approval_Mode, + + [Parameter()] + [System.String] + $User_Account_Control_Switch_to_the_secure_desktop_when_prompting_for_elevation, + + [Parameter()] + [System.String] + $User_Account_Control_Virtualize_file_and_registry_write_failures_to_per_user_locations + ) + + $registryPolicies = @() + $systemAccessPolicies = @() + $nonComplaintPolicies = @() + $securityOptionList = Get-PolicyOptionList -ModuleName MSFT_SecurityOption + $securityOptionData = Get-PolicyOptionData -FilePath $("$PSScriptRoot\SecurityOptionData.psd1").Normalize() + $script:seceditOutput = "$env:TEMP\Secedit-OutPut.txt" + $securityOptionsToAddInf = "$env:TEMP\securityOptionsToAdd.inf" + + $desiredPolicies = $PSBoundParameters.GetEnumerator() | Where-Object -FilterScript { $PSItem.key -in $securityOptionList } + + foreach ( $policy in $desiredPolicies ) + { + $testParameters = @{ + Name = 'Test' + $policy.Key = $policy.Value + Verbose = $false + } + + # define what policies are not in a desired state so we only add those policies + # that need to be changed to the INF + $isInDesiredState = Test-TargetResource @testParameters + if ( -not ( $isInDesiredState ) ) + { + $policyKey = $policy.Key + $policyData = $securityOptionData.$policyKey + $nonComplaintPolicies += $policyKey + + if ( $policyData.Option.GetEnumerator().Name -eq 'String' ) + { + if ( [String]::IsNullOrWhiteSpace( $policyData.Option.String ) ) + { + $newValue = $policy.Value + } + else + { + if( $policy.Key -eq 'Interactive_logon_Message_text_for_users_attempting_to_log_on' ) + { + $message = Format-LogonMessage -Message $policy.Value + $newValue = "$($policyData.Option.String)" + $message + } + else + { + $newValue = "$($policyData.Option.String)" + "$($policy.Value)" + } + } + } + elseIf ( $policy.Key -eq 'Network_security_Configure_encryption_types_allowed_for_Kerberos' ) + { + $newValue = ConvertTo-KerberosEncryptionValue -EncryptionType $policy.Value + } + else + { + $newValue = $($policyData.Option[$policy.value]) + } + + if ( $policyData.Section -eq 'System Access' ) + { + $systemAccessPolicies += "$($policyData.Value)=$newValue" + } + else + { + $registryPolicies += "$($policyData.Value)=$newValue" + } + } + } + + $infTemplate = Add-PolicyOption -SystemAccessPolicies $systemAccessPolicies -RegistryPolicies $registryPolicies + + Out-File -InputObject $infTemplate -FilePath $securityOptionsToAddInf -Encoding unicode -Force + + Invoke-Secedit -InfPath $securityOptionsToAddInf -SecEditOutput $script:seceditOutput + + $successResult = Test-TargetResource @PSBoundParameters + + if ( $successResult -eq $false ) + { + throw "$($script:localizedData.SetFailed -f $($nonComplaintPolicies -join ','))" + } + else + { + Write-Verbose -Message ($script:localizedData.SetSuccess) + } +} + + +<# + .SYNOPSIS + Tests the current security options against the desired configuration +#> +function Test-TargetResource +{ + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingPlainTextForPassword", "")] + [Diagnostics.CodeAnalysis.SuppressMessageAttribute("PSAvoidUsingUserNameAndPassWordParams", "")] + [CmdletBinding()] + [OutputType([System.Boolean])] + param + ( + [Parameter(Mandatory = $true)] + [System.String] + $Name, + + [Parameter()] + [ValidateSet("Enabled","Disabled")] + [System.String] + $Accounts_Administrator_account_status, + + [Parameter()] + [ValidateSet("This policy is disabled","Users cant add Microsoft accounts","Users cant add or log on with Microsoft accounts")] + [System.String] + $Accounts_Block_Microsoft_accounts, + + [Parameter()] + [ValidateSet("Enabled","Disabled")] + [System.String] + $Accounts_Guest_account_status, + + [Parameter()] + [ValidateSet("Enabled","Disabled")] + [System.String] + $Accounts_Limit_local_account_use_of_blank_passwords_to_console_logon_only, + + [Parameter()] + [System.String] + $Accounts_Rename_administrator_account, + + [Parameter()] + [System.String] + $Accounts_Rename_guest_account, + + [Parameter()] + [ValidateSet("Enabled","Disabled")] + [System.String] + $Audit_Audit_the_access_of_global_system_objects, + + [Parameter()] + [ValidateSet("Enabled","Disabled")] + [System.String] + $Audit_Audit_the_use_of_Backup_and_Restore_privilege, + + [Parameter()] + [ValidateSet("Enabled","Disabled")] + [System.String] + $Audit_Force_audit_policy_subcategory_settings_Windows_Vista_or_later_to_override_audit_policy_category_settings, + + [Parameter()] + [ValidateSet("Enabled","Disabled")] + [System.String] + $Audit_Shut_down_system_immediately_if_unable_to_log_security_audits, + + [Parameter()] + [System.String] + $DCOM_Machine_Access_Restrictions_in_Security_Descriptor_Definition_Language_SDDL_syntax, + + [Parameter()] + [System.String] + $DCOM_Machine_Launch_Restrictions_in_Security_Descriptor_Definition_Language_SDDL_syntax, + + [Parameter()] + [System.String] + $Devices_Allow_undock_without_having_to_log_on, + + [Parameter()] + [ValidateSet("Administrators","Administrators and Power Users","Administrators and Interactive Users")] + [System.String] + $Devices_Allowed_to_format_and_eject_removable_media, + + [Parameter()] + [System.String] + $Devices_Prevent_users_from_installing_printer_drivers, + + [Parameter()] + [System.String] + $Devices_Restrict_CD_ROM_access_to_locally_logged_on_user_only, + + [Parameter()] + [System.String] + $Devices_Restrict_floppy_access_to_locally_logged_on_user_only, + + [Parameter()] + [System.String] + $Domain_controller_Allow_server_operators_to_schedule_tasks, + + [Parameter()] + [System.String] + $Domain_controller_LDAP_server_signing_requirements, + + [Parameter()] + [System.String] + $Domain_controller_Refuse_machine_account_password_changes, + + [Parameter()] + [System.String] + $Domain_member_Digitally_encrypt_or_sign_secure_channel_data_always, + + [Parameter()] + [System.String] + $Domain_member_Digitally_encrypt_secure_channel_data_when_possible, + + [Parameter()] + [System.String] + $Domain_member_Digitally_sign_secure_channel_data_when_possible, + + [Parameter()] + [System.String] + $Domain_member_Disable_machine_account_password_changes, + + [Parameter()] + [System.String] + $Domain_member_Maximum_machine_account_password_age, + + [Parameter()] + [System.String] + $Domain_member_Require_strong_Windows_2000_or_later_session_key, + + [Parameter()] + [ValidateSet("User displayname, domain and user names","User display name only","Do not display user information")] + [System.String] + $Interactive_logon_Display_user_information_when_the_session_is_locked, + + [Parameter()] + [System.String] + $Interactive_logon_Do_not_display_last_user_name, + + [Parameter()] + [System.String] + $Interactive_logon_Do_not_require_CTRL_ALT_DEL, + + [Parameter()] + [System.String] + $Interactive_logon_Machine_account_lockout_threshold, + + [Parameter()] + [System.String] + $Interactive_logon_Machine_inactivity_limit, + + [Parameter()] + [System.String] + $Interactive_logon_Message_text_for_users_attempting_to_log_on, + + [Parameter()] + [System.String] + $Interactive_logon_Message_title_for_users_attempting_to_log_on, + + [Parameter()] + [System.String] + $Interactive_logon_Number_of_previous_logons_to_cache_in_case_domain_controller_is_not_available, + + [Parameter()] + [System.String] + $Interactive_logon_Prompt_user_to_change_password_before_expiration, + + [Parameter()] + [System.String] + $Interactive_logon_Require_Domain_Controller_authentication_to_unlock_workstation, + + [Parameter()] + [System.String] + $Interactive_logon_Require_smart_card, + + [Parameter()] + [ValidateSet("No Action","Lock workstation","Force logoff","Disconnect if a remote Remote Desktop Services session")] + [System.String] + $Interactive_logon_Smart_card_removal_behavior, + + [Parameter()] + [System.String] + $Microsoft_network_client_Digitally_sign_communications_always, + + [Parameter()] + [System.String] + $Microsoft_network_client_Digitally_sign_communications_if_server_agrees, + + [Parameter()] + [System.String] + $Microsoft_network_client_Send_unencrypted_password_to_third_party_SMB_servers, + + [Parameter()] + [System.String] + $Microsoft_network_server_Amount_of_idle_time_required_before_suspending_session, + + [Parameter()] + [System.String] + $Microsoft_network_server_Attempt_S4U2Self_to_obtain_claim_information, + + [Parameter()] + [System.String] + $Microsoft_network_server_Digitally_sign_communications_always, + + [Parameter()] + [System.String] + $Microsoft_network_server_Digitally_sign_communications_if_client_agrees, + + [Parameter()] + [System.String] + $Microsoft_network_server_Disconnect_clients_when_logon_hours_expire, + + [Parameter()] + [ValidateSet("Off","Accept if provided by the client","Required from client")] + [System.String] + $Microsoft_network_server_Server_SPN_target_name_validation_level, + + [Parameter()] + [System.String] + $Network_access_Allow_anonymous_SID_Name_translation, + + [Parameter()] + [System.String] + $Network_access_Do_not_allow_anonymous_enumeration_of_SAM_accounts, + + [Parameter()] + [System.String] + $Network_access_Do_not_allow_anonymous_enumeration_of_SAM_accounts_and_shares, + + [Parameter()] + [System.String] + $Network_access_Do_not_allow_storage_of_passwords_and_credentials_for_network_authentication, + + [Parameter()] + [System.String] + $Network_access_Let_Everyone_permissions_apply_to_anonymous_users, + + [Parameter()] + [System.String] + $Network_access_Named_Pipes_that_can_be_accessed_anonymously, + + [Parameter()] + [System.String] + $Network_access_Remotely_accessible_registry_paths, + + [Parameter()] + [System.String] + $Network_access_Remotely_accessible_registry_paths_and_subpaths, + + [Parameter()] + [System.String] + $Network_access_Restrict_anonymous_access_to_Named_Pipes_and_Shares, + + [Parameter()] + [System.String] + $Network_access_Shares_that_can_be_accessed_anonymously, + + [Parameter()] + [ValidateSet("Classic - Local users authenticate as themselves","Guest only - Local users authenticate as Guest")] + [System.String] + $Network_access_Sharing_and_security_model_for_local_accounts, + + [Parameter()] + [System.String] + $Network_security_Allow_Local_System_to_use_computer_identity_for_NTLM, + + [Parameter()] + [System.String] + $Network_security_Allow_LocalSystem_NULL_session_fallback, + + [Parameter()] + [System.String] + $Network_Security_Allow_PKU2U_authentication_requests_to_this_computer_to_use_online_identities, + + [Parameter()] + [ValidateSet("DES_CBC_CRC","DES_CBC_MD5","RC4_HMAC_MD5","AES128_HMAC_SHA1","AES256_HMAC_SHA1")] + [System.String[]] + $Network_security_Configure_encryption_types_allowed_for_Kerberos, + + [Parameter()] + [System.String] + $Network_security_Do_not_store_LAN_Manager_hash_value_on_next_password_change, + + [Parameter()] + [System.String] + $Network_security_Force_logoff_when_logon_hours_expire, + + [Parameter()] + [ValidateSet("Send LM & NTLM responses","Send LM & NTLM - use NTLMv2 session security if negotiated","Send NTLM responses only","Send NTLMv2 responses only","Send NTLMv2 responses only. Refuse LM","Send NTLMv2 responses only. Refuse LM & NTLM")] + [System.String] + $Network_security_LAN_Manager_authentication_level, + + [Parameter()] + [ValidateSet("None","Negotiate Signing","Require Signing")] + [System.String] + $Network_security_LDAP_client_signing_requirements, + + [Parameter()] + [ValidateSet("Require NTLMv2 session security","Require 128-bit encryption","Both options checked")] + [System.String] + $Network_security_Minimum_session_security_for_NTLM_SSP_based_including_secure_RPC_clients, + + [Parameter()] + [ValidateSet("Require NTLMv2 session security","Require 128-bit encryption","Both options checked")] + [System.String] + $Network_security_Minimum_session_security_for_NTLM_SSP_based_including_secure_RPC_servers, + + [Parameter()] + [System.String] + $Network_security_Restrict_NTLM_Add_remote_server_exceptions_for_NTLM_authentication, + + [Parameter()] + [System.String] + $Network_security_Restrict_NTLM_Add_server_exceptions_in_this_domain, + + [Parameter()] + [ValidateSet("Disabled","Enable auditing for domain accounts","Enable auditing for all accounts")] + [System.String] + $Network_Security_Restrict_NTLM_Incoming_NTLM_Traffic, + + [Parameter()] + [ValidateSet("Disable","Enable for domain accounts to domain servers","Enable for domain accounts","Enable for domain servers","Enable all")] + [System.String] + $Network_Security_Restrict_NTLM_NTLM_authentication_in_this_domain, + + [Parameter()] + [ValidateSet("Allow all","Deny all domain accounts","Deny all accounts")] + [System.String] + $Network_Security_Restrict_NTLM_Outgoing_NTLM_traffic_to_remote_servers, + + [Parameter()] + [ValidateSet("Disable","Deny for domain accounts to domain servers","Deny for domain accounts","Deny for domain servers","Deny all")] + [System.String] + $Network_Security_Restrict_NTLM_Audit_Incoming_NTLM_Traffic, + + [Parameter()] + [ValidateSet("Allow all","Audit all","Deny all")] + [System.String] + $Network_Security_Restrict_NTLM_Audit_NTLM_authentication_in_this_domain, + + [Parameter()] + [System.String] + $Recovery_console_Allow_automatic_administrative_logon, + + [Parameter()] + [System.String] + $Recovery_console_Allow_floppy_copy_and_access_to_all_drives_and_folders, + + [Parameter()] + [System.String] + $Shutdown_Allow_system_to_be_shut_down_without_having_to_log_on, + + [Parameter()] + [System.String] + $Shutdown_Clear_virtual_memory_pagefile, + + [Parameter()] + [ValidateSet("User input is not required when new keys are stored and used","User is prompted when the key is first used","User must enter a password each time they use a key")] + [System.String] + $System_cryptography_Force_strong_key_protection_for_user_keys_stored_on_the_computer, + + [Parameter()] + [System.String] + $System_cryptography_Use_FIPS_compliant_algorithms_for_encryption_hashing_and_signing, + + [Parameter()] + [System.String] + $System_objects_Require_case_insensitivity_for_non_Windows_subsystems, + + [Parameter()] + [System.String] + $System_objects_Strengthen_default_permissions_of_internal_system_objects_eg_Symbolic_Links, + + [Parameter()] + [System.String] + $System_settings_Optional_subsystems, + + [Parameter()] + [System.String] + $System_settings_Use_Certificate_Rules_on_Windows_Executables_for_Software_Restriction_Policies, + + [Parameter()] + [System.String] + $User_Account_Control_Admin_Approval_Mode_for_the_Built_in_Administrator_account, + + [Parameter()] + [System.String] + $User_Account_Control_Allow_UIAccess_applications_to_prompt_for_elevation_without_using_the_secure_desktop, + + [Parameter()] + [ValidateSet("Elevate without prompting","Prompt for credentials on the secure desktop","Prompt for consent on the secure desktop","Prompt for credentials","Prompt for consent","Prompt for consent for non-Windows binaries")] + [System.String] + $User_Account_Control_Behavior_of_the_elevation_prompt_for_administrators_in_Admin_Approval_Mode, + + [Parameter()] + [ValidateSet("Automatically deny elevation request","Prompt for credentials on the secure desktop","Prompt for crendentials")] + [System.String] + $User_Account_Control_Behavior_of_the_elevation_prompt_for_standard_users, + + [Parameter()] + [System.String] + $User_Account_Control_Detect_application_installations_and_prompt_for_elevation, + + [Parameter()] + [System.String] + $User_Account_Control_Only_elevate_executables_that_are_signed_and_validated, + + [Parameter()] + [System.String] + $User_Account_Control_Only_elevate_UIAccess_applications_that_are_installed_in_secure_locations, + + [Parameter()] + [System.String] + $User_Account_Control_Run_all_administrators_in_Admin_Approval_Mode, + + [Parameter()] + [System.String] + $User_Account_Control_Switch_to_the_secure_desktop_when_prompting_for_elevation, + + [Parameter()] + [System.String] + $User_Account_Control_Virtualize_file_and_registry_write_failures_to_per_user_locations + ) + + $currentSecurityOptions = Get-TargetResource -Name $Name -Verbose:0 + + $desiredSecurityOptions = $PSBoundParameters + + foreach ( $policy in $desiredSecurityOptions.Keys ) + { + if ( $currentSecurityOptions.ContainsKey( $policy ) ) + { + if ( $policy -eq 'Interactive_logon_Message_text_for_users_attempting_to_log_on' ) + { + $desiredSecurityOptionValue = Format-LogonMessage -Message $desiredSecurityOptions[$policy] + } + else + { + $desiredSecurityOptionValue = $desiredSecurityOptions[$policy] + } + Write-Verbose -Message ( $script:localizedData.TestingPolicy -f $policy ) + Write-Verbose -Message ( $script:localizedData.PoliciesBeingCompared` + -f $($currentSecurityOptions[$policy] -join ',' ), $($desiredSecurityOptionValue -join ',' ) ) + + if ( $desiredSecurityOptionValue -is [array] ) + { + $compareResult = Compare-Array -ReferenceObject $currentSecurityOptions[$policy] -DifferenceObject $desiredSecurityOptionValue + + if ( -not $compareResult ) + { + return $false + } + } + else + { + if ( $currentSecurityOptions[$policy] -ne $desiredSecurityOptionValue ) + { + return $false + } + } + } + } + + # if the code made it this far we must be in a desired state + return $true +} + +<# + .SYNOPSIS + Convert Kerberos encrytion numeric values to their corresponding value names + + .PARAMETER EncryptionValue + Specifies the encryption value to convert +#> +function ConvertTo-KerberosEncryptionOption +{ + [OutputType([string[]])] + [CmdletBinding()] + param + ( + [Parameter()] + [string] + $EncryptionValue + ) + + $reverseOptions = @{} + $kerberosSecurityOptionName = "Network_security_Configure_encryption_types_allowed_for_Kerberos" + $securityOptionData = Get-PolicyOptionData -FilePath $("$PSScriptRoot\SecurityOptionData.psd1").Normalize() + $kerberosOptionValues = $securityOptionData[$kerberosSecurityOptionName].Option + + $newValue = $(($EncryptionValue -split ',')[-1]) + + foreach ( $entry in $kerberosOptionValues.GetEnumerator() ) + { + $value = ($entry.Value -split ',')[-1] + $reverseOptions.Add( $value, $entry.Name ) + } + + $result = $reverseOptions.Keys | Where-Object -FilterScript { $_ -band $newValue } | ForEach-Object -Process {$reverseOptions.Get_Item($_)} + return $result +} + +<# + .SYNOPSIS + Converts Kerberos encryption options to their corresponding numeric value + + .PARAMETER EncryptionType + Specifies the EncryptionType that will be converted to their corresponding value(s). + + .NOTES + The Network_security_Configure_encryption_types_allowed_for_Kerberos option has multiple values. + Each value is represented by a number that is incremented exponentially by 2. When allowing + multiple options we have to add those values. +#> +function ConvertTo-KerberosEncryptionValue +{ + [OutputType([string])] + [CmdletBinding()] + param + ( + [Parameter(Mandatory=$true)] + [ValidateSet('DES_CBC_CRC','DES_CBC_MD5','RC4_HMAC_MD5','AES256_HMAC_SHA1','AES128_HMAC_SHA1')] + [string[]] + $EncryptionType + ) + + $sumResult = 0 + $kerberosSecurityOptionName = "Network_security_Configure_encryption_types_allowed_for_Kerberos" + $securityOptionData = Get-PolicyOptionData -FilePath $("$PSScriptRoot\SecurityOptionData.psd1").Normalize() + $kerberosOptionValues = $securityOptionData[$kerberosSecurityOptionName].Option + + foreach ( $type in $EncryptionType ) + { + $sumResult = $sumResult + ($kerberosOptionValues.$type -split ',')[-1] + } + + return $( '4,' + $sumResult ) +} + +<# + .SYNOPSIS + Compares values that have array as a type +#> +function Compare-Array +{ + [OutputType([bool])] + [CmdletBinding()] + param + ( + [Parameter()] + [string[]] + $ReferenceObject, + + [Parameter()] + [string[]] + $DifferenceObject + + ) + + return $null -eq (Compare-Object $ReferenceObject $DifferenceObject ).SideIndicator +} + +<# + .SYNOPSIS + Secedit.exe uses an INI file with security policies and their associated values (key value pair). + The value to a policy must be on one line. If the message is a multiple line message a comma is used + for the line break and if a comma is intended for grammar it must be surrounded with double quotes. + + .PARAMETER Message + The logon message to be formated +#> +function Format-LogonMessage +{ + [OutputType([string])] + [CmdletBinding()] + param + ( + [Parameter(Mandatory = $true)] + [string] + $Message + ) + + $formatText = $Message -split '\n' + + if ( $formatText.count -gt 1 ) + { + $lines = $formatText -split '\n' | ForEach-Object -Process { ($PSItem -replace ',','","').Trim() } + $resultValue = $lines -join ',' + } + else + { + $resultValue = $formatText + } + + return $resultValue +} + +Export-ModuleMember -Function *-TargetResource + diff --git a/lib/puppet_x/dsc_resources/SecurityPolicyDsc/DSCResources/MSFT_SecurityOption/MSFT_SecurityOption.schema.mof b/lib/puppet_x/dsc_resources/SecurityPolicyDsc/DSCResources/MSFT_SecurityOption/MSFT_SecurityOption.schema.mof new file mode 100644 index 000000000..ac3346d97 --- /dev/null +++ b/lib/puppet_x/dsc_resources/SecurityPolicyDsc/DSCResources/MSFT_SecurityOption/MSFT_SecurityOption.schema.mof @@ -0,0 +1,102 @@ + +[ClassVersion("1.0.0.0"), FriendlyName("SecurityOption")] +class MSFT_SecurityOption : OMI_BaseResource +{ + [Key, Description("Describes the security option to be managed. This could be anything as long as it is unique")] String Name; + [Write, ValueMap{"Enabled","Disabled"}, Values{"Enabled","Disabled"}] String Accounts_Administrator_account_status; + [Write, ValueMap{"This policy is disabled","Users cant add Microsoft accounts","Users cant add or log on with Microsoft accounts"}, Values{"This policy is disabled","Users cant add Microsoft accounts","Users cant add or log on with Microsoft accounts"}] String Accounts_Block_Microsoft_accounts; + [Write, ValueMap{"Enabled","Disabled"}, Values{"Enabled","Disabled"}] String Accounts_Guest_account_status; + [Write, ValueMap{"Enabled","Disabled"}, Values{"Enabled","Disabled"}] String Accounts_Limit_local_account_use_of_blank_passwords_to_console_logon_only; + [Write] String Accounts_Rename_administrator_account; + [Write] String Accounts_Rename_guest_account; + [Write, ValueMap{"Enabled","Disabled"}, Values{"Enabled","Disabled"}] String Audit_Audit_the_access_of_global_system_objects; + [Write, ValueMap{"Enabled","Disabled"}, Values{"Enabled","Disabled"}] String Audit_Audit_the_use_of_Backup_and_Restore_privilege; + [Write, ValueMap{"Enabled","Disabled"}, Values{"Enabled","Disabled"}] String Audit_Force_audit_policy_subcategory_settings_Windows_Vista_or_later_to_override_audit_policy_category_settings; + [Write, ValueMap{"Enabled","Disabled"}, Values{"Enabled","Disabled"}] String Audit_Shut_down_system_immediately_if_unable_to_log_security_audits; + [Write] String DCOM_Machine_Access_Restrictions_in_Security_Descriptor_Definition_Language_SDDL_syntax; + [Write] String DCOM_Machine_Launch_Restrictions_in_Security_Descriptor_Definition_Language_SDDL_syntax; + [Write] String Devices_Allow_undock_without_having_to_log_on; + [Write, ValueMap{"Administrators","Administrators and Power Users","Administrators and Interactive Users"}, Values{"Administrators","Administrators and Power Users","Administrators and Interactive Users"}] String Devices_Allowed_to_format_and_eject_removable_media; + [Write] String Devices_Prevent_users_from_installing_printer_drivers; + [Write] String Devices_Restrict_CD_ROM_access_to_locally_logged_on_user_only; + [Write] String Devices_Restrict_floppy_access_to_locally_logged_on_user_only; + [Write] String Domain_controller_Allow_server_operators_to_schedule_tasks; + [Write] String Domain_controller_LDAP_server_signing_requirements; + [Write] String Domain_controller_Refuse_machine_account_password_changes; + [Write] String Domain_member_Digitally_encrypt_or_sign_secure_channel_data_always; + [Write] String Domain_member_Digitally_encrypt_secure_channel_data_when_possible; + [Write] String Domain_member_Digitally_sign_secure_channel_data_when_possible; + [Write] String Domain_member_Disable_machine_account_password_changes; + [Write] String Domain_member_Maximum_machine_account_password_age; + [Write] String Domain_member_Require_strong_Windows_2000_or_later_session_key; + [Write, ValueMap{"User displayname, domain and user names","User display name only","Do not display user information"}, Values{"User displayname, domain and user names","User display name only","Do not display user information"}] String Interactive_logon_Display_user_information_when_the_session_is_locked; + [Write] String Interactive_logon_Do_not_display_last_user_name; + [Write] String Interactive_logon_Do_not_require_CTRL_ALT_DEL; + [Write] String Interactive_logon_Machine_account_lockout_threshold; + [Write] String Interactive_logon_Machine_inactivity_limit; + [Write] String Interactive_logon_Message_text_for_users_attempting_to_log_on; + [Write] String Interactive_logon_Message_title_for_users_attempting_to_log_on; + [Write] String Interactive_logon_Number_of_previous_logons_to_cache_in_case_domain_controller_is_not_available; + [Write] String Interactive_logon_Prompt_user_to_change_password_before_expiration; + [Write] String Interactive_logon_Require_Domain_Controller_authentication_to_unlock_workstation; + [Write] String Interactive_logon_Require_smart_card; + [Write, ValueMap{"No Action","Lock workstation","Force logoff","Disconnect if a remote Remote Desktop Services session"}, Values{"No Action","Lock workstation","Force logoff","Disconnect if a remote Remote Desktop Services session"}] String Interactive_logon_Smart_card_removal_behavior; + [Write] String Microsoft_network_client_Digitally_sign_communications_always; + [Write] String Microsoft_network_client_Digitally_sign_communications_if_server_agrees; + [Write] String Microsoft_network_client_Send_unencrypted_password_to_third_party_SMB_servers; + [Write] String Microsoft_network_server_Amount_of_idle_time_required_before_suspending_session; + [Write] String Microsoft_network_server_Attempt_S4U2Self_to_obtain_claim_information; + [Write] String Microsoft_network_server_Digitally_sign_communications_always; + [Write] String Microsoft_network_server_Digitally_sign_communications_if_client_agrees; + [Write] String Microsoft_network_server_Disconnect_clients_when_logon_hours_expire; + [Write, ValueMap{"Off","Accept if provided by the client","Required from client"}, Values{"Off","Accept if provided by the client","Required from client"}] String Microsoft_network_server_Server_SPN_target_name_validation_level; + [Write] String Network_access_Allow_anonymous_SID_Name_translation; + [Write] String Network_access_Do_not_allow_anonymous_enumeration_of_SAM_accounts; + [Write] String Network_access_Do_not_allow_anonymous_enumeration_of_SAM_accounts_and_shares; + [Write] String Network_access_Do_not_allow_storage_of_passwords_and_credentials_for_network_authentication; + [Write] String Network_access_Let_Everyone_permissions_apply_to_anonymous_users; + [Write] String Network_access_Named_Pipes_that_can_be_accessed_anonymously; + [Write] String Network_access_Remotely_accessible_registry_paths; + [Write] String Network_access_Remotely_accessible_registry_paths_and_subpaths; + [Write] String Network_access_Restrict_anonymous_access_to_Named_Pipes_and_Shares; + [Write] String Network_access_Shares_that_can_be_accessed_anonymously; + [Write, ValueMap{"Classic - Local users authenticate as themselves","Guest only - Local users authenticate as Guest"}, Values{"Classic - Local users authenticate as themselves","Guest only - Local users authenticate as Guest"}] String Network_access_Sharing_and_security_model_for_local_accounts; + [Write] String Network_security_Allow_Local_System_to_use_computer_identity_for_NTLM; + [Write] String Network_security_Allow_LocalSystem_NULL_session_fallback; + [Write] String Network_Security_Allow_PKU2U_authentication_requests_to_this_computer_to_use_online_identities; + [Write, ValueMap{"DES_CBC_CRC","DES_CBC_MD5","RC4_HMAC_MD5","AES128_HMAC_SHA1","AES256_HMAC_SHA1"}, Values{"DES_CBC_CRC","DES_CBC_MD5","RC4_HMAC_MD5","AES128_HMAC_SHA1","AES256_HMAC_SHA1"}] String Network_security_Configure_encryption_types_allowed_for_Kerberos[]; + [Write] String Network_security_Do_not_store_LAN_Manager_hash_value_on_next_password_change; + [Write] String Network_security_Force_logoff_when_logon_hours_expire; + [Write, ValueMap{"Send LM & NTLM responses","Send LM & NTLM - use NTLMv2 session security if negotiated","Send NTLM responses only","Send NTLMv2 responses only","Send NTLMv2 responses only. Refuse LM","Send NTLMv2 responses only. Refuse LM & NTLM"}, Values{"Send LM & NTLM responses","Send LM & NTLM - use NTLMv2 session security if negotiated","Send NTLM responses only","Send NTLMv2 responses only","Send NTLMv2 responses only. Refuse LM","Send NTLMv2 responses only. Refuse LM & NTLM"}] String Network_security_LAN_Manager_authentication_level; + [Write, ValueMap{"None","Negotiate Signing","Require Signing"}, Values{"None","Negotiate Signing","Require Signing"}] String Network_security_LDAP_client_signing_requirements; + [Write, ValueMap{"Require NTLMv2 session security","Require 128-bit encryption","Both options checked"}, Values{"Require NTLMv2 session security","Require 128-bit encryption","Both options checked"}] String Network_security_Minimum_session_security_for_NTLM_SSP_based_including_secure_RPC_clients; + [Write, ValueMap{"Require NTLMv2 session security","Require 128-bit encryption","Both options checked"}, Values{"Require NTLMv2 session security","Require 128-bit encryption","Both options checked"}] String Network_security_Minimum_session_security_for_NTLM_SSP_based_including_secure_RPC_servers; + [Write] String Network_security_Restrict_NTLM_Add_remote_server_exceptions_for_NTLM_authentication; + [Write] String Network_security_Restrict_NTLM_Add_server_exceptions_in_this_domain; + [Write, ValueMap{"Disabled","Enable auditing for domain accounts","Enable auditing for all accounts"}, Values{"Disabled","Enable auditing for domain accounts","Enable auditing for all accounts"}] String Network_Security_Restrict_NTLM_Incoming_NTLM_Traffic; + [Write, ValueMap{"Disable","Enable for domain accounts to domain servers","Enable for domain accounts","Enable for domain servers","Enable all"}, Values{"Disable","Enable for domain accounts to domain servers","Enable for domain accounts","Enable for domain servers","Enable all"}] String Network_Security_Restrict_NTLM_NTLM_authentication_in_this_domain; + [Write, ValueMap{"Allow all","Deny all domain accounts","Deny all accounts"}, Values{"Allow all","Deny all domain accounts","Deny all accounts"}] String Network_Security_Restrict_NTLM_Outgoing_NTLM_traffic_to_remote_servers; + [Write, ValueMap{"Disable","Deny for domain accounts to domain servers","Deny for domain accounts","Deny for domain servers","Deny all"}, Values{"Disable","Deny for domain accounts to domain servers","Deny for domain accounts","Deny for domain servers","Deny all"}] String Network_Security_Restrict_NTLM_Audit_Incoming_NTLM_Traffic; + [Write, ValueMap{"Allow all","Audit all","Deny all"}, Values{"Allow all","Audit all","Deny all"}] String Network_Security_Restrict_NTLM_Audit_NTLM_authentication_in_this_domain; + [Write] String Recovery_console_Allow_automatic_administrative_logon; + [Write] String Recovery_console_Allow_floppy_copy_and_access_to_all_drives_and_folders; + [Write] String Shutdown_Allow_system_to_be_shut_down_without_having_to_log_on; + [Write] String Shutdown_Clear_virtual_memory_pagefile; + [Write, ValueMap{"User input is not required when new keys are stored and used","User is prompted when the key is first used","User must enter a password each time they use a key"}, Values{"User input is not required when new keys are stored and used","User is prompted when the key is first used","User must enter a password each time they use a key"}] String System_cryptography_Force_strong_key_protection_for_user_keys_stored_on_the_computer; + [Write] String System_cryptography_Use_FIPS_compliant_algorithms_for_encryption_hashing_and_signing; + [Write] String System_objects_Require_case_insensitivity_for_non_Windows_subsystems; + [Write] String System_objects_Strengthen_default_permissions_of_internal_system_objects_eg_Symbolic_Links; + [Write] String System_settings_Optional_subsystems; + [Write] String System_settings_Use_Certificate_Rules_on_Windows_Executables_for_Software_Restriction_Policies; + [Write] String User_Account_Control_Admin_Approval_Mode_for_the_Built_in_Administrator_account; + [Write] String User_Account_Control_Allow_UIAccess_applications_to_prompt_for_elevation_without_using_the_secure_desktop; + [Write, ValueMap{"Elevate without prompting","Prompt for credentials on the secure desktop","Prompt for consent on the secure desktop","Prompt for credentials","Prompt for consent","Prompt for consent for non-Windows binaries"}, Values{"Elevate without prompting","Prompt for credentials on the secure desktop","Prompt for consent on the secure desktop","Prompt for credentials","Prompt for consent","Prompt for consent for non-Windows binaries"}] String User_Account_Control_Behavior_of_the_elevation_prompt_for_administrators_in_Admin_Approval_Mode; + [Write, ValueMap{"Automatically deny elevation request","Prompt for credentials on the secure desktop","Prompt for crendentials"}, Values{"Automatically deny elevation request","Prompt for credentials on the secure desktop","Prompt for crendentials"}] String User_Account_Control_Behavior_of_the_elevation_prompt_for_standard_users; + [Write] String User_Account_Control_Detect_application_installations_and_prompt_for_elevation; + [Write] String User_Account_Control_Only_elevate_executables_that_are_signed_and_validated; + [Write] String User_Account_Control_Only_elevate_UIAccess_applications_that_are_installed_in_secure_locations; + [Write] String User_Account_Control_Run_all_administrators_in_Admin_Approval_Mode; + [Write] String User_Account_Control_Switch_to_the_secure_desktop_when_prompting_for_elevation; + [Write] String User_Account_Control_Virtualize_file_and_registry_write_failures_to_per_user_locations; +}; + diff --git a/lib/puppet_x/dsc_resources/SecurityPolicyDsc/DSCResources/MSFT_SecurityOption/SecurityOptionData.psd1 b/lib/puppet_x/dsc_resources/SecurityPolicyDsc/DSCResources/MSFT_SecurityOption/SecurityOptionData.psd1 new file mode 100644 index 000000000..b09387dd8 --- /dev/null +++ b/lib/puppet_x/dsc_resources/SecurityPolicyDsc/DSCResources/MSFT_SecurityOption/SecurityOptionData.psd1 @@ -0,0 +1,870 @@ + +@{ + "Accounts_Administrator_account_status" = @{ + Value = 'EnableAdminAccount' + Section = 'System Access' + Option = @{ + "Enabled" = '1' + "Disabled" = '0' + } + } + + "Accounts_Block_Microsoft_accounts" = @{ + Value = "MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\NoConnectedUser" + Section = 'Registry Values' + Option = @{ + "This policy is disabled" = '4,0' + "Users cant add Microsoft accounts" = '4,1' + "Users cant add or log on with Microsoft accounts" = '4,3' + } + } + + "Accounts_Guest_account_status" = @{ + Value = 'EnableGuestAccount' + Section = 'System Access' + Option = @{ + "Enabled" = '1' + "Disabled" = '0' + } + } + + "Accounts_Limit_local_account_use_of_blank_passwords_to_console_logon_only" = @{ + Value = "MACHINE\System\CurrentControlSet\Control\Lsa\LimitBlankPasswordUse" + Section = 'Registry Values' + Option = @{ + Enabled = '4,1' + Disabled = '4,0' + } + } + + "Accounts_Rename_administrator_account" = @{ + Value = 'NewAdministratorName' + Section = 'System Access' + Option = @{ + String = '' # supply name of administrator account + } + } + + "Accounts_Rename_guest_account" = @{ + Value = 'NewGuestName' + Section = 'System Access' + Option = @{ + String = '' # supply name of guest account + } + } + + "Audit_Audit_the_access_of_global_system_objects" = @{ + Value = "MACHINE\System\CurrentControlSet\Control\Lsa\AuditBaseObjects" + Section = 'Registry Values' + Option = @{ + Enabled = '4,1' + Disabled = '4,0' + } + } + + "Audit_Audit_the_use_of_Backup_and_Restore_privilege" = @{ + Value = "MACHINE\System\CurrentControlSet\Control\Lsa\FullPrivilegeAuditing" + Section = 'Registry Values' + Option = @{ + Enabled = '3,1' + Disabled = '3,0' + } + } + + "Audit_Force_audit_policy_subcategory_settings_Windows_Vista_or_later_to_override_audit_policy_category_settings" = @{ + Value = "MACHINE\System\CurrentControlSet\Control\Lsa\SCENoApplyLegacyAuditPolicy" + Section = 'Registry Values' + Option = @{ + Enabled = '4,1' + Disabled = '4,0' + } + } + + "Audit_Shut_down_system_immediately_if_unable_to_log_security_audits" = @{ + Value = "MACHINE\System\CurrentControlSet\Control\Lsa\CrashOnAuditFail" + Section = 'Registry Values' + Option = @{ + Enabled = '4,1' + Disabled = '4,0' + } + } + + "DCOM_Machine_Access_Restrictions_in_Security_Descriptor_Definition_Language_SDDL_syntax" = @{ + Value = "MACHINE\Software\Policies\Microsoft\Windows NT\DCOM\MachineAccessRestriction" + Section = 'Registry Values' + Option = @{ + String = '1,' # + + } + } + + "DCOM_Machine_Launch_Restrictions_in_Security_Descriptor_Definition_Language_SDDL_syntax" = @{ + Value = "MACHINE\Software\Policies\Microsoft\Windows NT\DCOM\MachineLaunchRestriction" + Section = 'Registry Values' + Option = @{ + String = '1,' # + + } + } + + "Devices_Allow_undock_without_having_to_log_on" = @{ + Value = "MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\UndockWithoutLogon" + Section = 'Registry Values' + Option = @{ + Enabled = '4,1' + Disabled = '4,0' + } + } + + "Devices_Allowed_to_format_and_eject_removable_media" = @{ + Value = "MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\AllocateDASD" + Section = 'Registry Values' + Option = @{ + 'Administrators' = '1,"0"' + 'Administrators and Power Users' = '1,"1"' + 'Administrators and Interactive Users' = '1,"2"' + } + } + + "Devices_Prevent_users_from_installing_printer_drivers" = @{ + Value = "MACHINE\System\CurrentControlSet\Control\Print\Providers\LanMan Print Services\Servers\AddPrinterDrivers" + Section = 'Registry Values' + Option = @{ + Enabled = '4,1' + Disabled = '4,0' + } + } + + "Devices_Restrict_CD_ROM_access_to_locally_logged_on_user_only" = @{ + Value = "MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\AllocateCDRoms" + Section = 'Registry Values' + Option = @{ + Enabled = '1,"1"' + Disabled = '1,"0"' + } + } + + "Devices_Restrict_floppy_access_to_locally_logged_on_user_only" = @{ + Value = "MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\AllocateFloppies" + Section = 'Registry Values' + Option = @{ + Enabled = '1,"1"' + Disabled = '1,"0"' + } + } + + "Domain_controller_Allow_server_operators_to_schedule_tasks" = @{ + Value = "MACHINE\System\CurrentControlSet\Control\Lsa\SubmitControl" + Section = 'Registry Values' + Option = @{ + Enabled = '4,1' + Disabled = '4,0' + } + } + + "Domain_controller_LDAP_server_signing_requirements" = @{ + Value = "MACHINE\System\CurrentControlSet\Services\NTDS\Parameters\LDAPServerIntegrity" + Section = 'Registry Values' + Option = @{ + 'None' = '4,1' + 'Require Signing' = '4,2' + } + } + + "Domain_controller_Refuse_machine_account_password_changes" = @{ + Value = "MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters\RefusePasswordChange" + Section = 'Registry Values' + Option = @{ + Enabled = '4,1' + Disabled = '4,0' + } + } + + "Domain_member_Digitally_encrypt_or_sign_secure_channel_data_always" = @{ + Value = "MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters\RequireSignOrSeal" + Section = 'Registry Values' + Option = @{ + Enabled = '4,1' + Disabled = '4,0' + } + } + + "Domain_member_Digitally_encrypt_secure_channel_data_when_possible" = @{ + Value = "MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters\SealSecureChannel" + Section = 'Registry Values' + Option = @{ + Enabled = '4,1' + Disabled = '4,0' + } + } + + "Domain_member_Digitally_sign_secure_channel_data_when_possible" = @{ + Value = "MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters\SignSecureChannel" + Section = 'Registry Values' + Option = @{ + Enabled = '4,1' + Disabled = '4,0' + } + } + + "Domain_member_Disable_machine_account_password_changes" = @{ + Value = "MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters\DisablePasswordChange" + Section = 'Registry Values' + Option = @{ + Enabled = '4,1' + Disabled = '4,0' + } + } + + "Domain_member_Maximum_machine_account_password_age" = @{ + Value = "MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters\MaximumPasswordAge" + Section = 'Registry Values' + Option = @{ + String = "4," # + + } + } + + "Domain_member_Require_strong_Windows_2000_or_later_session_key" = @{ + Value = "MACHINE\System\CurrentControlSet\Services\Netlogon\Parameters\RequireStrongKey" + Section = 'Registry Values' + Option = @{ + Enabled = '4,1' + Disabled = '4,0' + } + } + + "Interactive_logon_Display_user_information_when_the_session_is_locked" = @{ + Value = "MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\DontDisplayLockedUserId" + Section = 'Registry Values' + Option = @{ + 'User displayname, domain and user names' = '4,1' + 'User display name only' = '4,2' + 'Do not display user information' = '4,3' + } + } + + "Interactive_logon_Do_not_display_last_user_name" = @{ + Value = "MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\DontDisplayLastUserName" + Section = 'Registry Values' + Option = @{ + Enabled = '4,1' + Disabled = '4,0' + } + } + + "Interactive_logon_Do_not_require_CTRL_ALT_DEL" = @{ + Value = "MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\DisableCAD" + Section = 'Registry Values' + Option = @{ + Enabled = '4,1' + Disabled = '4,0' + } + } + + "Interactive_logon_Machine_account_lockout_threshold" = @{ + Value = "MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\MaxDevicePasswordFailedAttempts" + Section = 'Registry Values' + Option = @{ + String = "4," # + + } + } + + "Interactive_logon_Machine_inactivity_limit" = @{ + Value = "MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\InactivityTimeoutSecs" + Section = 'Registry Values' + Option = @{ + String = "4," # + + } + } + + "Interactive_logon_Message_text_for_users_attempting_to_log_on" = @{ + Value = "MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\LegalNoticeText" + Section = 'Registry Values' + Option = @{ + String = "7," # + + } + } + + "Interactive_logon_Message_title_for_users_attempting_to_log_on" = @{ + Value = "MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\LegalNoticeCaption" + Section = 'Registry Values' + Option = @{ + String = "1," # + + } + } + + "Interactive_logon_Number_of_previous_logons_to_cache_in_case_domain_controller_is_not_available" = @{ + Value = "MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\CachedLogonsCount" + Section = 'Registry Values' + Option = @{ + String = "1," # + + } + } + + "Interactive_logon_Prompt_user_to_change_password_before_expiration" = @{ + Value = "MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\PasswordExpiryWarning" + Section = 'Registry Values' + Option = @{ + String = "4," # + + } + } + + "Interactive_logon_Require_Domain_Controller_authentication_to_unlock_workstation" = @{ + Value = "MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\ForceUnlockLogon" + Section = 'Registry Values' + Option = @{ + Enabled = '4,1' + Disabled = '4,0' + } + } + + "Interactive_logon_Require_smart_card" = @{ + Value = "MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\ScForceOption" + Section = 'Registry Values' + Option = @{ + Enabled = '4,1' + Disabled = '4,0' + } + } + + "Interactive_logon_Smart_card_removal_behavior" = @{ + Value = "MACHINE\Software\Microsoft\Windows NT\CurrentVersion\Winlogon\ScRemoveOption" + Section = 'Registry Values' + Option = @{ + 'No Action' = '1,"0"' + 'Lock workstation' = '1,"1"' + 'Force logoff' = '1,"2"' + 'Disconnect if a remote Remote Desktop Services session' = '1,"3"' + } + } + + "Microsoft_network_client_Digitally_sign_communications_always" = @{ + Value = "MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters\RequireSecuritySignature" + Section = 'Registry Values' + Option = @{ + Enabled = '4,1' + Disabled = '4,0' + } + } + + "Microsoft_network_client_Digitally_sign_communications_if_server_agrees" = @{ + Value = "MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters\EnableSecuritySignature" + Section = 'Registry Values' + Option = @{ + Enabled = '4,1' + Disabled = '4,0' + } + } + + "Microsoft_network_client_Send_unencrypted_password_to_third_party_SMB_servers" = @{ + Value = "MACHINE\System\CurrentControlSet\Services\LanmanWorkstation\Parameters\EnablePlainTextPassword" + Section = 'Registry Values' + Option = @{ + Enabled = '4,1' + Disabled = '4,0' + } + } + + "Microsoft_network_server_Amount_of_idle_time_required_before_suspending_session" = @{ + Value = "MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters\AutoDisconnect" + Section = 'Registry Values' + Option = @{ + String = '4,' # + + } + } + + "Microsoft_network_server_Attempt_S4U2Self_to_obtain_claim_information" = @{ + Value = "MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters\EnableS4U2SelfForClaims" + Section = 'Registry Values' + Option = @{ + Default = '4,0' + Enabled = '4,1' + Disabled = '4,2' + } + } + + "Microsoft_network_server_Digitally_sign_communications_always" = @{ + Value = "MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters\RequireSecuritySignature" + Section = 'Registry Values' + Option = @{ + Enabled = '4,1' + Disabled = '4,0' + } + } + + "Microsoft_network_server_Digitally_sign_communications_if_client_agrees" = @{ + Value = "MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters\EnableSecuritySignature" + Section = 'Registry Values' + Option = @{ + Enabled = '4,1' + Disabled = '4,0' + } + } + + "Microsoft_network_server_Disconnect_clients_when_logon_hours_expire" = @{ + Value = "MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters\EnableForcedLogOff" + Section = 'Registry Values' + Option = @{ + Enabled = '4,1' + Disabled = '4,0' + } + } + + "Microsoft_network_server_Server_SPN_target_name_validation_level" = @{ + Value = "MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters\SmbServerNameHardeningLevel " + Section = 'Registry Values' + Option = @{ + 'Off' = '4,0' + 'Accept if provided by the client' = '4,1' + 'Required from client' = '4,2' + } + } + + "Network_access_Allow_anonymous_SID_Name_translation" = @{ + Value = 'LSAAnonymousNameLookup' + Section = 'System Access' + Option = @{ + Enabled = '1' + Disabled = '0' + } + } + + "Network_access_Do_not_allow_anonymous_enumeration_of_SAM_accounts" = @{ + Value = "MACHINE\System\CurrentControlSet\Control\Lsa\RestrictAnonymousSAM" + Section = 'Registry Values' + Option = @{ + Enabled = '4,1' + Disabled = '4,0' + } + } + + "Network_access_Do_not_allow_anonymous_enumeration_of_SAM_accounts_and_shares" = @{ + Value = "MACHINE\System\CurrentControlSet\Control\Lsa\RestrictAnonymous" + Section = 'Registry Values' + Option = @{ + Enabled = '4,1' + Disabled = '4,0' + } + } + + "Network_access_Do_not_allow_storage_of_passwords_and_credentials_for_network_authentication" = @{ + Value = "MACHINE\System\CurrentControlSet\Control\Lsa\DisableDomainCreds" + Section = 'Registry Values' + Option = @{ + Enabled = '4,1' + Disabled = '4,0' + } + } + + "Network_access_Let_Everyone_permissions_apply_to_anonymous_users" = @{ + Value = "MACHINE\System\CurrentControlSet\Control\Lsa\EveryoneIncludesAnonymous" + Section = 'Registry Values' + Option = @{ + Enabled = '4,1' + Disabled = '4,0' + } + } + + "Network_access_Named_Pipes_that_can_be_accessed_anonymously" = @{ + Value = "MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters\NullSessionPipes" + Section = 'Registry Values' + Option = @{ + String = '7,' # + accounts (Identities seperated by commas) + } + } + + "Network_access_Remotely_accessible_registry_paths" = @{ + Value = "MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedExactPaths\Machine" + Section = 'Registry Values' + Option = @{ + String = '7,' # + accounts (Identities seperated by commas) + } + } + + "Network_access_Remotely_accessible_registry_paths_and_subpaths" = @{ + Value = "MACHINE\System\CurrentControlSet\Control\SecurePipeServers\Winreg\AllowedPaths\Machine" + Section = 'Registry Values' + Option = @{ + String = '7,' # + accounts (Identities seperated by commas) + } + } + + "Network_access_Restrict_anonymous_access_to_Named_Pipes_and_Shares" = @{ + Value = "MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters\RestrictNullSessAccess" + Section = 'Registry Values' + Option = @{ + Enabled = '4,1' + Disabled = '4,0' + } + } + + "Network_access_Shares_that_can_be_accessed_anonymously" = @{ + Value = "MACHINE\System\CurrentControlSet\Services\LanManServer\Parameters\NullSessionShares" + Section = 'Registry Values' + Option = @{ + String = '7,' # + accounts (Identities seperated by commas) + } + } + + "Network_access_Sharing_and_security_model_for_local_accounts" = @{ + Value = "MACHINE\System\CurrentControlSet\Control\Lsa\ForceGuest" + Section = 'Registry Values' + Option = @{ + 'Classic - Local users authenticate as themselves' = '4,0' + 'Guest only - Local users authenticate as Guest' = '4,1' + } + } + + "Network_security_Allow_Local_System_to_use_computer_identity_for_NTLM" = @{ + Value = "MACHINE\System\CurrentControlSet\Control\Lsa\UseMachineId" + Section = 'Registry Values' + Option = @{ + Enabled = '4,1' + Disabled = '4,0' + } + } + + "Network_security_Allow_LocalSystem_NULL_session_fallback" = @{ + Value = "MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0\allownullsessionfallback" + Section = 'Registry Values' + Option = @{ + Enabled = '4,1' + Disabled = '4,0' + } + } + + "Network_Security_Allow_PKU2U_authentication_requests_to_this_computer_to_use_online_identities" = @{ + Value = "MACHINE\System\CurrentControlSet\Control\Lsa\pku2u\AllowOnlineID" + Section = 'Registry Values' + Option = @{ + Enabled = '4,1' + Disabled = '4,0' + } + } + + "Network_security_Configure_encryption_types_allowed_for_Kerberos" = @{ + Value = "MACHINE\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters\SupportedEncryptionTypes" + Section = 'Registry Values' + Option = @{ + DES_CBC_CRC = '4,1' + DES_CBC_MD5 = '4,2' + RC4_HMAC_MD5 = '4,4' + AES128_HMAC_SHA1 = '4,8' + AES256_HMAC_SHA1 = '4,16' + } + } + + "Network_security_Do_not_store_LAN_Manager_hash_value_on_next_password_change" = @{ + Value = "MACHINE\System\CurrentControlSet\Control\Lsa\NoLMHash" + Section = 'Registry Values' + Option = @{ + Enabled = '4,1' + Disabled = '4,0' + } + } + + "Network_security_Force_logoff_when_logon_hours_expire" = @{ + Value = "ForceLogoffWhenHourExpire" + Section = 'System Access' + Option = @{ + Enabled = '1' + Disabled = '0' + } + } + + "Network_security_LAN_Manager_authentication_level" = @{ + Value = "MACHINE\System\CurrentControlSet\Control\Lsa\LmCompatibilityLevel" + Section = 'Registry Values' + Option = @{ + 'Send LM & NTLM responses' = '4,0' + 'Send LM & NTLM - use NTLMv2 session security if negotiated' = '4,1' + 'Send NTLM responses only' = '4,2' + 'Send NTLMv2 responses only' = '4,3' + 'Send NTLMv2 responses only. Refuse LM' = '4,4' + 'Send NTLMv2 responses only. Refuse LM & NTLM' = '4,5' + } + } + + "Network_security_LDAP_client_signing_requirements" = @{ + Value = "MACHINE\System\CurrentControlSet\Services\LDAP\LDAPClientIntegrity" + Section = 'Registry Values' + Option = @{ + 'None' = '4,0' + 'Negotiate Signing' = '4,1' + 'Require Signing' = '4,2' + } + } + + "Network_security_Minimum_session_security_for_NTLM_SSP_based_including_secure_RPC_clients" = @{ + Value = "MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0\NTLMMinClientSec" + Section = 'Registry Values' + Option = @{ + 'Require NTLMv2 session security' = '4,524288' + 'Require 128-bit encryption' = '4,536870912' + 'Both options checked' = '4,537395200' + } + } + + "Network_security_Minimum_session_security_for_NTLM_SSP_based_including_secure_RPC_servers" = @{ + Value = "MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0\NTLMMinServerSec" + Section = 'Registry Values' + Option = @{ + 'Require NTLMv2 session security' = '4,524288' + 'Require 128-bit encryption' = '4,536870912' + 'Both options checked' = '4,537395200' + } + } + + "Network_security_Restrict_NTLM_Add_remote_server_exceptions_for_NTLM_authentication" = @{ + Value = "MACHINE\System\CurrentControlSet\Control\Lsa\MSV1_0\ClientAllowedNTLMServers" + Section = 'Registry Values' + Option = @{ + String = '7,' #